diff -Nru openjdk-21-21.0.1+12/.jcheck/conf openjdk-21-21.0.2+13/.jcheck/conf --- openjdk-21-21.0.1+12/.jcheck/conf 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/.jcheck/conf 2024-01-16 16:19:00.000000000 +0000 @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=21.0.1 +version=21.0.2 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff -Nru openjdk-21-21.0.1+12/debian/changelog openjdk-21-21.0.2+13/debian/changelog --- openjdk-21-21.0.1+12/debian/changelog 2023-11-23 19:36:13.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/changelog 2024-01-17 12:14:57.000000000 +0000 @@ -1,8 +1,38 @@ -openjdk-21 (21.0.1+12-2~23.10) mantic-security; urgency=medium +openjdk-21 (21.0.2+13-1~23.10.1) mantic-security; urgency=high - * Upload to Ubuntu 23.10. + * OpenJDK 21.0.2 release, build 13. + - CVEs: + + CVE-2024-20918 + + CVE-2024-20919 + + CVE-2024-20921 + + CVE-2024-20945 + + CVE-2024-20952 + - Security fixes: + + JDK-8308204: Enhanced certificate processing. + + JDK-8314295: Enhance verification of verifier. + + JDK-8314307: Improve loop handling. + + JDK-8314468: Improve Compiler loops. + + JDK-8316976: Improve signature handling. + + JDK-8317547: Enhance TLS connection support. - -- Vladimir Petko Fri, 24 Nov 2023 08:36:13 +1300 + [ Pushkar Kulkarni ] + * debian/copyright: Fix whitespace issues. + * Minor improvements to the copyright-generator. + + [ Vladimir Petko ] + * d/copyright: Fix lintian warning. + * Generate d/watch to cope with early access and release builds. + + [ Matthias Klose ] + * Add sparc64 defines (patch by Adrian Glaubitz). Closes: #1057390. + * d/copyright: Fix source location. + * Update the arch-add-ports patch, taken from 22. + * Regenerate debian files. + + [ Pushkar Kulkarni ] + * Upload to Ubuntu 23.10 + + -- Matthias Klose Wed, 17 Jan 2024 13:14:57 +0100 openjdk-21 (21.0.1+12-2) unstable; urgency=medium diff -Nru openjdk-21-21.0.1+12/debian/control openjdk-21-21.0.2+13/debian/control --- openjdk-21-21.0.1+12/debian/control 2023-11-23 19:36:13.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/control 2024-01-17 12:14:57.000000000 +0000 @@ -13,7 +13,7 @@ openjdk-21-jdk-headless:native | openjdk-20-jdk-headless:native, libxtst-dev, libxi-dev, libxt-dev, libxaw7-dev, libxrender-dev, libcups2-dev, libasound2-dev, liblcms2-dev, libxinerama-dev, libkrb5-dev, xsltproc, libpcsclite-dev, libxrandr-dev, libelf-dev, libfontconfig1-dev, libgtk2.0-0 | libgtk-3-0, libfreetype-dev, libharfbuzz-dev, libffi-dev, libffi-dev:native, - zlib1g-dev:native, zlib1g-dev, libattr1-dev, libpng-dev, libjpeg-dev, libgif-dev, + zlib1g-dev:native, zlib1g-dev, libattr1-dev, libpng-dev, libjpeg-dev, libgif-dev, libnss3-dev (>= 2:3.17.1), openjdk-21-jdk-headless , Build-Depends-Indep: graphviz, pandoc, diff -Nru openjdk-21-21.0.1+12/debian/copyright openjdk-21-21.0.2+13/debian/copyright --- openjdk-21-21.0.1+12/debian/copyright 2023-11-23 19:34:46.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/copyright 2024-01-17 12:14:57.000000000 +0000 @@ -1,5 +1,5 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Files-Excluded: +Files-Excluded: .github/* .gitattributes src/java.base/share/native/libzip/zlib/* @@ -18,8 +18,8 @@ src/java.desktop/share/native/libjavajpeg/jv* src/java.desktop/share/native/libjavajpeg/ju* src/java.desktop/share/native/libjavajpeg/README -Source: https://github.com/openjdk/jdk -Comment: +Source: https://github.com/openjdk/jdk21u +Comment: Upstream Authors: OpenJDK: Oracle and/or its affiliates @@ -39,7 +39,7 @@ Matthias Klose Files: * -Copyrights: +Copyright: Copyright (c) 1996-2023 Oracle and/or its affiliates. Copyright (c) 1996-2003 Sun Microsystems, Inc. Copyright (c) 2009-2012 Red Hat, Inc. @@ -423,69 +423,44 @@ directories of modules under src/ ------------------------------------------------------------------------------ . - %% This notice is provided with respect to Dynalink v.5, + %% This notice is provided with respect to Cryptix AES v3.2.0, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . - Dynalink License + Cryptix General License . . - Copyright (c) 2009-2013, Attila Szegedi + Cryptix General License + . + Copyright (c) 1995-2005 The Cryptix Foundation Limited. + 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 the copyright holder nor the names of - 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 COPYRIGHT HOLDER - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + 1. Redistributions of source code must retain the 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 CRYPTIX FOUNDATION LIMITED 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 CRYPTIX FOUNDATION LIMITED 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. - . - . - . - --- end of LICENSE --- - . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to Apache Santuario v3.0.2, - which may be included with JRE 21, JDK 21 and OpenJDK 21 - . - --- begin of LICENSE --- - . - Apache 2.0 License: Refer to the copy under /usr/share/common-licenses - . - Apache Santuario Notice - . - . - Apache Santuario - XML Security for Java - Copyright 1999-2023 The Apache Software Foundation - . - This product includes software developed at - The Apache Software Foundation (http://www.apache.org/). - . - It was originally based on software copyright (c) 2001, Institute for - Data Communications Systems, . - . - The development of this software was partly funded by the European - Commission in the project in the ISIS Programme. + 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 product contains software that is - copyright (c) 2021, Oracle and/or its affiliates. . . --- end of LICENSE --- @@ -534,6 +509,48 @@ --- end of LICENSE --- . ------------------------------------------------------------------------------ + %% This notice is provided with respect to c-libutl 20160225, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + c-libutl License + . + . + This software is distributed under the terms of the BSD license. + . + == BSD LICENSE =============================================================== + . + (C) 2009 by Remo Dentato (rdentato@gmail.com) + . + . + 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. + . + 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. + . + http://opensource.org/licenses/bsd-license.php + . + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ %% This notice is provided with respect to Unicode Common Local Data Repository (CLDR) v43, which may be included with JRE 21, JDK 21 and OpenJDK 21 . @@ -650,522 +667,6 @@ --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to Mozilla Public Suffix List, - which may be included with JRE 21, JDK 21 and OpenJDK 21 - . - --- begin of LICENSE --- - . - Public Suffix Notice - . - You are receiving a copy of the Mozilla Public Suffix List in the following - file: /lib/security/public_suffix_list.dat. The terms of the - Oracle license do NOT apply to this file; it is licensed under the - Mozilla Public License 2.0, separately from the Oracle programs you receive. - If you do not wish to use the Public Suffix List, you may remove the - /lib/security/public_suffix_list.dat file. - . - 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/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/. - . - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the License. - . - . - MPL v2.0 - . - Mozilla Public License Version 2.0 - ================================== - . - 1. Definitions - -------------- - . - 1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - . - 1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - . - 1.3. "Contribution" - means Covered Software of a particular Contributor. - . - 1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - . - 1.5. "Incompatible With Secondary Licenses" - means - . - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - . - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - . - 1.6. "Executable Form" - means any form of the work other than Source Code Form. - . - 1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - . - 1.8. "License" - means this document. - . - 1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - . - 1.10. "Modifications" - means any of the following: - . - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - . - (b) any new file in Source Code Form that contains any Covered - Software. - . - 1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - . - 1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - . - 1.13. "Source Code Form" - means the form of the work preferred for making modifications. - . - 1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - . - 2. License Grants and Conditions - -------------------------------- - . - 2.1. Grants - . - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - . - (a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - . - (b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - . - 2.2. Effective Date - . - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - . - 2.3. Limitations on Grant Scope - . - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - . - (a) for any code that a Contributor has removed from Covered Software; - or - . - (b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - . - (c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - . - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - . - 2.4. Subsequent Licenses - . - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - . - 2.5. Representation - . - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights - to grant the rights to its Contributions conveyed by this License. - . - 2.6. Fair Use - . - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - . - 2.7. Conditions - . - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted - in Section 2.1. - . - 3. Responsibilities - ------------------- - . - 3.1. Distribution of Source Form - . - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - . - 3.2. Distribution of Executable Form - . - If You distribute Covered Software in Executable Form then: - . - (a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - . - (b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - . - 3.3. Distribution of a Larger Work - . - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - . - 3.4. Notices - . - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, - or limitations of liability) contained within the Source Code Form of - the Covered Software, except that You may alter any license notices to - the extent required to remedy known factual inaccuracies. - . - 3.5. Application of Additional Terms - . - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - . - 4. Inability to Comply Due to Statute or Regulation - --------------------------------------------------- - . - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Software due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description must - be placed in a text file included with all distributions of the Covered - Software under this License. Except to the extent prohibited by statute - or regulation, such description must be sufficiently detailed for a - recipient of ordinary skill to be able to understand it. - . - 5. Termination - -------------- - . - 5.1. The rights granted under this License will terminate automatically - if You fail to comply with any of its terms. However, if You become - compliant, then the rights granted under this License from a particular - Contributor are reinstated (a) provisionally, unless and until such - Contributor explicitly and finally terminates Your grants, and (b) on an - ongoing basis, if such Contributor fails to notify You of the - non-compliance by some reasonable means prior to 60 days after You have - come back into compliance. Moreover, Your grants from a particular - Contributor are reinstated on an ongoing basis if such Contributor - notifies You of the non-compliance by some reasonable means, this is the - first time You have received notice of non-compliance with this License - from such Contributor, and You become compliant prior to 30 days after - Your receipt of the notice. - . - 5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - . - 5.3. In the event of termination under Sections 5.1 or 5.2 above, all - end user license agreements (excluding distributors and resellers) which - have been validly granted by You or Your distributors under this License - prior to termination shall survive termination. - . - ************************************************************************ - * * - * 6. Disclaimer of Warranty * - * ------------------------- * - * * - * Covered Software is provided under this License on an "as is" * - * basis, without warranty of any kind, either expressed, implied, or * - * statutory, including, without limitation, warranties that the * - * Covered Software is free of defects, merchantable, fit for a * - * particular purpose or non-infringing. The entire risk as to the * - * quality and performance of the Covered Software is with You. * - * Should any Covered Software prove defective in any respect, You * - * (not any Contributor) assume the cost of any necessary servicing, * - * repair, or correction. This disclaimer of warranty constitutes an * - * essential part of this License. No use of any Covered Software is * - * authorized under this License except under this disclaimer. * - * * - ************************************************************************ - . - ************************************************************************ - * * - * 7. Limitation of Liability * - * -------------------------- * - * * - * Under no circumstances and under no legal theory, whether tort * - * (including negligence), contract, or otherwise, shall any * - * Contributor, or anyone who distributes Covered Software as * - * permitted above, be liable to You for any direct, indirect, * - * special, incidental, or consequential damages of any character * - * including, without limitation, damages for lost profits, loss of * - * goodwill, work stoppage, computer failure or malfunction, or any * - * and all other commercial damages or losses, even if such party * - * shall have been informed of the possibility of such damages. This * - * limitation of liability shall not apply to liability for death or * - * personal injury resulting from such party's negligence to the * - * extent applicable law prohibits such limitation. Some * - * jurisdictions do not allow the exclusion or limitation of * - * incidental or consequential damages, so this exclusion and * - * limitation may not apply to You. * - * * - ************************************************************************ - . - 8. Litigation - ------------- - . - Any litigation relating to this License may be brought only in the - courts of a jurisdiction where the defendant maintains its principal - place of business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. - Nothing in this Section shall prevent a party's ability to bring - cross-claims or counter-claims. - . - 9. Miscellaneous - ---------------- - . - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides - that the language of a contract shall be construed against the drafter - shall not be used to construe this License against a Contributor. - . - 10. Versions of the License - --------------------------- - . - 10.1. New Versions - . - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - . - 10.2. Effect of New Versions - . - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - . - 10.3. Modified Versions - . - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - . - 10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses - . - If You choose to distribute Source Code Form that is Incompatible With - Secondary Licenses under the terms of this version of the License, the - notice described in Exhibit B of this License must be attached. - . - Exhibit A - Source Code Form License Notice - ------------------------------------------- - . - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at https://mozilla.org/MPL/2.0/. - . - If it is not possible or desirable to put the notice in a particular - file, then You may include the notice in a location (such as a LICENSE - file in a relevant directory) where a recipient would be likely to look - for such a notice. - . - You may add additional accurate notices of copyright ownership. - . - Exhibit B - "Incompatible With Secondary Licenses" Notice - --------------------------------------------------------- - . - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. - . - . - . - --- end of LICENSE --- - . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to The Unicode Standard, Unicode Character Database, Version 15.0.0, - which may be included with JRE 21, JDK 21 and OpenJDK 21 - . - --- begin of LICENSE --- - . - Unicode Character Database - . - . - UNICODE, INC. LICENSE AGREEMENT - 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 - DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), - YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE - TERMS AND CONDITIONS OF THIS AGREEMENT. - IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE - THE DATA FILES OR SOFTWARE. - . - COPYRIGHT AND PERMISSION NOTICE - . - Copyright © 1991-2022 Unicode, Inc. All rights reserved. - Distributed under the Terms of Use in https://www.unicode.org/copyright.html. - . - Permission is hereby granted, free of charge, to any person obtaining - a copy of the Unicode data files and any associated documentation - (the "Data Files") or Unicode software and any associated documentation - (the "Software") to deal in the Data Files or Software - without restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, and/or sell copies of - the Data Files or Software, and to permit persons to whom the Data Files - or Software are furnished to do so, provided that either - (a) this copyright and permission notice appear with all copies - of the Data Files or Software, or - (b) this copyright and permission notice appear in associated - Documentation. - . - THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS - NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 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 THE DATA FILES OR SOFTWARE. - . - Except as contained in this notice, the name of a copyright holder - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in these Data Files or Software without prior - written authorization of the copyright holder. - . - === http://www.unicode.org/copyright.html content === - Unicode (R) Copyright and Terms of Use - For the general privacy policy governing access to this site, see the Unicode Privacy Policy. - . - Unicode Copyright - Copyright (C) 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 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. - . - . - . - . - . - --- end of LICENSE --- - . - ------------------------------------------------------------------------------ %% This notice is provided with respect to International Components for Unicode (ICU4J) v72.1, which may be included with JRE 21, JDK 21 and OpenJDK 21 . @@ -1691,821 +1192,842 @@ --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to Cryptix AES v3.2.0, - which may be included with JRE 21, JDK 21 and OpenJDK 21 - . - --- begin of LICENSE --- - . - Cryptix General License - . - . - Cryptix General License - . - Copyright (c) 1995-2005 The Cryptix Foundation Limited. - 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 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 CRYPTIX FOUNDATION LIMITED 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 CRYPTIX FOUNDATION LIMITED 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. - . - . - . - --- end of LICENSE --- - . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to c-libutl 20160225, + %% This notice is provided with respect to Mozilla Public Suffix List, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . - c-libutl License - . - . - This software is distributed under the terms of the BSD license. - . - == BSD LICENSE =============================================================== - . - (C) 2009 by Remo Dentato (rdentato@gmail.com) - . - . - 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. - . - 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. - . - http://opensource.org/licenses/bsd-license.php - . + Public Suffix Notice . + You are receiving a copy of the Mozilla Public Suffix List in the following + file: /lib/security/public_suffix_list.dat. The terms of the + Oracle license do NOT apply to this file; it is licensed under the + Mozilla Public License 2.0, separately from the Oracle programs you receive. + If you do not wish to use the Public Suffix List, you may remove the + /lib/security/public_suffix_list.dat file. . - --- end of LICENSE --- + 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/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/. . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to jQuery v3.6.1, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + for the specific language governing rights and limitations under the License. . - --- begin of LICENSE --- . - jQuery License + MPL v2.0 . - jQuery v 3.6.1 - Copyright OpenJS Foundation and other contributors, https://openjsf.org/ + Mozilla Public License Version 2.0 + ================================== . - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: + 1. Definitions + -------------- . - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. + 1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + 1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. . - ****************************************** + 1.3. "Contribution" + means Covered Software of a particular Contributor. . - The jQuery JavaScript Library v3.6.1 also includes Sizzle.js + 1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. . - Sizzle.js includes the following license: + 1.5. "Incompatible With Secondary Licenses" + means . - Copyright JS Foundation and other contributors, https://js.foundation/ + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or . - This software consists of voluntary contributions made by many - individuals. For exact contribution history, see the revision history - available at https://github.com/jquery/sizzle + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. . - The following license applies to all parts of this software except as - documented below: + 1.6. "Executable Form" + means any form of the work other than Source Code Form. . - ==== + 1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. . - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: + 1.8. "License" + means this document. . - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. + 1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + 1.10. "Modifications" + means any of the following: . - ==== + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or . - All files located in the node_modules and external directories are - externally maintained libraries used by this software which have their - own licenses; we recommend you read them, as their terms may differ from - the terms above. + (b) any new file in Source Code Form that contains any Covered + Software. . - ********************* + 1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. . + 1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. . + 1.13. "Source Code Form" + means the form of the work preferred for making modifications. . - --- end of LICENSE --- + 1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to jQuery UI v1.13.2, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + 2. License Grants and Conditions + -------------------------------- . - --- begin of LICENSE --- + 2.1. Grants . - jQuery UI License + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: . - Copyright jQuery Foundation and other contributors, https://jquery.org/ + (a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and . - This software consists of voluntary contributions made by many - individuals. For exact contribution history, see the revision history - available at https://github.com/jquery/jquery-ui + (b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. . - The following license applies to all parts of this software except as - documented below: + 2.2. Effective Date . - ==== + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. . - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: + 2.3. Limitations on Grant Scope . - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + (a) for any code that a Contributor has removed from Covered Software; + or . - ==== + (b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or . - Copyright and related rights for sample code are waived via CC0. Sample - code is defined as all source code contained within the demos directory. + (c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. . - CC0: http://creativecommons.org/publicdomain/zero/1.0/ + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). . - ==== + 2.4. Subsequent Licenses . - All files located in the node_modules and external directories are - externally maintained libraries used by this software which have their - own licenses; we recommend you read them, as their terms may differ from - the terms above. + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). . + 2.5. Representation . + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights + to grant the rights to its Contributions conveyed by this License. . - --- end of LICENSE --- + 2.6. Fair Use . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to IAIK (Institute for Applied Information Processing and Communication) PKCS#11 wrapper files v1, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. . - --- begin of LICENSE --- + 2.7. Conditions . - IAIK License + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted + in Section 2.1. . + 3. Responsibilities + ------------------- . - Copyright (c) 2002 Graz University of Technology. All rights reserved. + 3.1. Distribution of Source Form . - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. . - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + 3.2. Distribution of Executable Form . - 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. + If You distribute Covered Software in Executable Form then: . - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: + (a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and . - "This product includes software developed by IAIK of Graz University of - Technology." + (b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. . - Alternately, this acknowledgment may appear in the software itself, if and - wherever such third-party acknowledgments normally appear. + 3.3. Distribution of a Larger Work . - 4. The names "Graz University of Technology" and "IAIK of Graz University of - Technology" must not be used to endorse or promote products derived from this - software without prior written permission. + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). . - 5. Products derived from this software may not be called "IAIK PKCS Wrapper", - nor may "IAIK" appear in their name, without prior written permission of - Graz University of Technology. + 3.4. Notices . - THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED 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 - LICENSOR 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. + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, + or limitations of liability) contained within the Source Code Form of + the Covered Software, except that You may alter any license notices to + the extent required to remedy known factual inaccuracies. . + 3.5. Application of Additional Terms . + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. . - --- end of LICENSE --- + 4. Inability to Comply Due to Statute or Regulation + --------------------------------------------------- . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to OASIS PKCS #11 Cryptographic Token Interface v3.0, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Software due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description must + be placed in a text file included with all distributions of the Covered + Software under this License. Except to the extent prohibited by statute + or regulation, such description must be sufficiently detailed for a + recipient of ordinary skill to be able to understand it. . - --- begin of LICENSE --- + 5. Termination + -------------- . - OASIS PKCS #11 Cryptographic Token Interface License + 5.1. The rights granted under this License will terminate automatically + if You fail to comply with any of its terms. However, if You become + compliant, then the rights granted under this License from a particular + Contributor are reinstated (a) provisionally, unless and until such + Contributor explicitly and finally terminates Your grants, and (b) on an + ongoing basis, if such Contributor fails to notify You of the + non-compliance by some reasonable means prior to 60 days after You have + come back into compliance. Moreover, Your grants from a particular + Contributor are reinstated on an ongoing basis if such Contributor + notifies You of the non-compliance by some reasonable means, this is the + first time You have received notice of non-compliance with this License + from such Contributor, and You become compliant prior to 30 days after + Your receipt of the notice. . + 5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. . - Copyright © OASIS Open 2020. All Rights Reserved. + 5.3. In the event of termination under Sections 5.1 or 5.2 above, all + end user license agreements (excluding distributors and resellers) which + have been validly granted by You or Your distributors under this License + prior to termination shall survive termination. . - All capitalized terms in the following text have the meanings - assigned to them in the OASIS Intellectual Property Rights Policy (the - "OASIS IPR Policy"). The full Policy may be found at the OASIS website: - [http://www.oasis-open.org/policies-guidelines/ipr] + ************************************************************************ + * * + * 6. Disclaimer of Warranty * + * ------------------------- * + * * + * Covered Software is provided under this License on an "as is" * + * basis, without warranty of any kind, either expressed, implied, or * + * statutory, including, without limitation, warranties that the * + * Covered Software is free of defects, merchantable, fit for a * + * particular purpose or non-infringing. The entire risk as to the * + * quality and performance of the Covered Software is with You. * + * Should any Covered Software prove defective in any respect, You * + * (not any Contributor) assume the cost of any necessary servicing, * + * repair, or correction. This disclaimer of warranty constitutes an * + * essential part of this License. No use of any Covered Software is * + * authorized under this License except under this disclaimer. * + * * + ************************************************************************ . - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it or - assist in its implementation may be prepared, copied, published, and - distributed, in whole or in part, without restriction of any kind, - provided that the above copyright notice and this section are included - on all such copies and derivative works. However, this document itself - may not be modified in any way, including by removing the copyright - notice or references to OASIS, except as needed for the purpose of - developing any document or deliverable produced by an OASIS Technical - Committee (in which case the rules applicable to copyrights, as set - forth in the OASIS IPR Policy, must be followed) or as required to - translate it into languages other than English. + ************************************************************************ + * * + * 7. Limitation of Liability * + * -------------------------- * + * * + * Under no circumstances and under no legal theory, whether tort * + * (including negligence), contract, or otherwise, shall any * + * Contributor, or anyone who distributes Covered Software as * + * permitted above, be liable to You for any direct, indirect, * + * special, incidental, or consequential damages of any character * + * including, without limitation, damages for lost profits, loss of * + * goodwill, work stoppage, computer failure or malfunction, or any * + * and all other commercial damages or losses, even if such party * + * shall have been informed of the possibility of such damages. This * + * limitation of liability shall not apply to liability for death or * + * personal injury resulting from such party's negligence to the * + * extent applicable law prohibits such limitation. Some * + * jurisdictions do not allow the exclusion or limitation of * + * incidental or consequential damages, so this exclusion and * + * limitation may not apply to You. * + * * + ************************************************************************ . - The limited permissions granted above are perpetual and will not be - revoked by OASIS or its successors or assigns. + 8. Litigation + ------------- . - This document and the information contained herein is provided on an - "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. OASIS - AND ITS MEMBERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR - CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THIS DOCUMENT OR ANY - PART THEREOF. + Any litigation relating to this License may be brought only in the + courts of a jurisdiction where the defendant maintains its principal + place of business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. + Nothing in this Section shall prevent a party's ability to bring + cross-claims or counter-claims. . - [OASIS requests that any OASIS Party or any other party that - believes it has patent claims that would necessarily be infringed by - implementations of this OASIS Standards Final Deliverable, to notify - OASIS TC Administrator and provide an indication of its willingness to - grant patent licenses to such patent claims in a manner consistent with - the IPR Mode of the OASIS Technical Committee that produced this - deliverable.] + 9. Miscellaneous + ---------------- . - [OASIS invites any party to contact the OASIS TC Administrator if it - is aware of a claim of ownership of any patent claims that would - necessarily be infringed by implementations of this OASIS Standards - Final Deliverable by a patent holder that is not willing to provide a - license to such patent claims in a manner consistent with the IPR Mode - of the OASIS Technical Committee that produced this OASIS Standards - Final Deliverable. OASIS may include such claims on its website, but - disclaims any obligation to do so.] + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides + that the language of a contract shall be construed against the drafter + shall not be used to construe this License against a Contributor. . - [OASIS takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to pertain - to the implementation or use of the technology described in this OASIS - Standards Final Deliverable or the extent to which any license under - such rights might or might not be available; neither does it represent - that it has made any effort to identify any such rights. Information on - OASIS' procedures with respect to rights in any document or deliverable - produced by an OASIS Technical Committee can be found on the OASIS - website. Copies of claims of rights made available for publication and - any assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this OASIS Standards - Final Deliverable, can be obtained from the OASIS TC Administrator. - OASIS makes no representation that any information or list of - intellectual property rights will at any time be complete, or that any - claims in such list are, in fact, Essential Claims.] + 10. Versions of the License + --------------------------- . + 10.1. New Versions . + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. . - --- end of LICENSE --- + 10.2. Effect of New Versions . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to Apache Xalan v2.7.2, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. . - --- begin of LICENSE --- + 10.3. Modified Versions . - Apache Xalan Notice + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). . + 10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses . - ====================================================================================== - == NOTICE file corresponding to the section 4d of the Apache License, Version 2.0, == - == in this case for the Apache Xalan distribution. == - ====================================================================================== + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. . - This product includes software developed by - The Apache Software Foundation (http://www.apache.org/). + Exhibit A - Source Code Form License Notice + ------------------------------------------- . - Specifically, we only include the XSLTC portion of the source from the Xalan distribution. - The Xalan project has two processors: an interpretive one (Xalan Interpretive) and a - compiled one (The XSLT Compiler (XSLTC)). We *only* use the XSLTC part of Xalan; We use - the source from the packages that are part of the XSLTC sources. + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at https://mozilla.org/MPL/2.0/. . - Portions of this software was originally based on the following: + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to look + for such a notice. . - - software copyright (c) 1999-2002, Lotus Development Corporation., http://www.lotus.com. - - software copyright (c) 2001-2002, Sun Microsystems., http://www.sun.com. - - software copyright (c) 2003, IBM Corporation., http://www.ibm.com. - - voluntary contributions made by Ovidiu Predescu (ovidiu@cup.hp.com) on behalf of the - Apache Software Foundation and was originally developed at Hewlett Packard Company. + You may add additional accurate notices of copyright ownership. . + Exhibit B - "Incompatible With Secondary Licenses" Notice + --------------------------------------------------------- . + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. . - Apache 2.0 License: Refer to the copy under /usr/share/common-licenses . . --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to CUP Parser Generator for Java v 0.11b, + %% This notice is provided with respect to The Unicode Standard, Unicode Character Database, Version 15.0.0, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . - CUP Parser Generator License - . + Unicode Character Database . - Copyright 1996-2015 by Scott Hudson, Frank Flannery, C. Scott Ananian, Michael Petter . - Permission to use, copy, modify, and distribute this software and its - documentation for any purpose and without fee is hereby granted, provided - that the above copyright notice appear in all copies and that both - the copyright notice and this permission notice and warranty disclaimer - appear in supporting documentation, and that the names of the authors or - their employers not be used in advertising or publicity pertaining to - distribution of the software without specific, written prior permission. - . - The authors and their employers disclaim all warranties with regard to - this software, including all implied warranties of merchantability and - fitness. In no event shall the authors or their employers be liable for - any special, 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. + UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE . - --- + See Terms of Use for definitions of Unicode Inc.'s + Data Files and Software. . - This is an open source license. It is also GPL-Compatible (see entry for - "Standard ML of New Jersey"). The portions of CUP output which are hard-coded - into the CUP source code are (naturally) covered by this same license, as is - the CUP runtime code linked with the generated parser. + NOTICE TO USER: Carefully read the following legal agreement. + BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S + DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), + YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE + TERMS AND CONDITIONS OF THIS AGREEMENT. + IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE + THE DATA FILES OR SOFTWARE. . + COPYRIGHT AND PERMISSION NOTICE . + Copyright © 1991-2022 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in https://www.unicode.org/copyright.html. . - --- end of LICENSE --- + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Unicode data files and any associated documentation + (the "Data Files") or Unicode software and any associated documentation + (the "Software") to deal in the Data Files or Software + without restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, and/or sell copies of + the Data Files or Software, and to permit persons to whom the Data Files + or Software are furnished to do so, provided that either + (a) this copyright and permission notice appear with all copies + of the Data Files or Software, or + (b) this copyright and permission notice appear in associated + Documentation. . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to Apache Commons Byte Code Engineering Library (BCEL) Version 6.7.0, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 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 THE DATA FILES OR SOFTWARE. . - --- begin of LICENSE --- + Except as contained in this notice, the name of a copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in these Data Files or Software without prior + written authorization of the copyright holder. . - Apache Commons BCEL Notice + === http://www.unicode.org/copyright.html content === + Unicode (R) Copyright and Terms of Use + For the general privacy policy governing access to this site, see the Unicode Privacy Policy. . + Unicode Copyright + Copyright (C) 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/ . - Apache Commons BCEL - Copyright 2004-2022 The Apache Software Foundation + Unicode Data Files do not include PDF online code charts under the directory: + https://www.unicode.org/Public/ . - This product includes software developed at - The Apache Software Foundation (https://www.apache.org/). + 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. . . . - Apache 2.0 License: Refer to the copy under /usr/share/common-licenses . . --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to Apache Xerces v2.12.2, + %% This notice is provided with respect to Eastman Kodak Company: Portions of color management and imaging software, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . - Apache Xerces Notice - . - ========================================================================= - == NOTICE file corresponding to section 4(d) of the Apache License, == - == Version 2.0, in this case for the Apache Xerces Java distribution. == - ========================================================================= - . - Apache Xerces Java - Copyright 1999-2022 The Apache Software Foundation - . - This product includes software developed at - The Apache Software Foundation (http://www.apache.org/). - . - Portions of this software were originally based on the following: - - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. - - software copyright (c) 1999, Sun Microsystems., http://www.sun.com. - - voluntary contributions made by Paul Eng on behalf of the - Apache Software Foundation that were originally developed at iClick, Inc., - software copyright (c) 1999. + Eastman Kodak Notice . + Portions Copyright Eastman Kodak Company 1991-2003 . - Apache 2.0 License: Refer to the copy under /usr/share/common-licenses . . --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to DOM Level 3 Core Specification v1.0, + %% This notice is provided with respect to The FreeType Project: Freetype v2.13.0, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . - W3C Software Notice - . - Copyright © 2004 World Wide Web Consortium, (Massachusetts Institute of Technology, - European Research Consortium for Informatics and Mathematics, Keio University). - All Rights Reserved. - . - The DOM bindings are published under the W3C Software Copyright Notice and License. - The software license requires "Notice of any changes or modifications to the W3C - files, including the date changes were made." Consequently, modified versions of - the DOM bindings must document that they do not conform to the W3C standard; in the - case of the IDL definitions, the pragma prefix can no longer be 'w3c.org'; in the - case of the Java language binding, the package names can no longer be in the - 'org.w3c' package. - . - . - W3C License - . . - W3C SOFTWARE NOTICE AND LICENSE - . - http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 - . - This work (and included software, documentation such as READMEs, or other - related items) is being provided by the copyright holders under the following - license. By obtaining, using and/or copying this work, you (the licensee) - agree that you have read, understood, and will comply with the following terms - and conditions. - . - Permission to copy, modify, and distribute this software and its - documentation, with or without modification, for any purpose and without fee - or royalty is hereby granted, provided that you include the following on ALL - copies of the software and documentation or portions thereof, including - modifications: - . - 1.The full text of this NOTICE in a location viewable to users of the - redistributed or derivative work. - . - 2.Any pre-existing intellectual property disclaimers, notices, or terms and - conditions. If none exist, the W3C Software Short Notice should be included - (hypertext is preferred, text is permitted) within the body of any - redistributed or derivative code. + FreeType Notice . - 3.Notice of any changes or modifications to the files, including the date - changes were made. (We recommend you provide URIs to the location from - which the code is derived.) . - THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS - MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT - LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR - PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY - THIRD PARTY PATENTS,COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + FreeType comes with two licenses from which you can choose the one + which fits your needs best. . - COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL - OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR - DOCUMENTATION. The name and trademarks of copyright holders may NOT be used - in advertising or publicity pertaining to the software without specific, - written prior permission. Title to copyright in this software and any - associated documentation will at all times remain with copyright holders. + The FreeType License (FTL) is the most commonly used one. It is + a BSD-style license with a credit clause and thus compatible with + the GNU Public License (GPL) version 3, but not with the + GPL version 2. . - ____________________________________ + The GNU General Public License (GPL), version 2. Use it for all + projects which use the GPLv2 also, or which need a license + compatible to the GPLv2. . - This formulation of W3C's notice and license became active on December 31 - 2002. This version removes the copyright ownership notice such that this - license can be used with materials other than those owned by the W3C, reflects - that ERCIM is now a host of the W3C, includes references to this specific - dated version of the license, and removes the ambiguous grant of "use". - Otherwise, this version is the same as the previous version and is written so - as to preserve the Free Software Foundation's assessment of GPL compatibility - and OSI's certification under the Open Source Definition. Please see our - Copyright FAQ for common questions about using materials from our site, - including specific terms and conditions for packages like libwww, Amaya, and - Jigsaw. Other questions about this notice can be directed to - site-policy@w3.org. . . + FreeType License . - --- end of LICENSE --- . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to JLine v3.22.0, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + Copyright (C) 1996-2023 by David Turner, Robert Wilhelm, and Werner Lemberg. + Copyright (C) 2007-2023 by Dereg Clegg and Michael Toftdal. + Copyright (C) 1996-2023 by Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. + Copyright (C) 2022-2023 by David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and + Copyright (C) 2004-2023 by Masatake YAMATO and Redhat K.K. + Copyright (C) 2007-2023 by Derek Clegg and Michael Toftdal. + Copyright (C) 2003-2023 by Masatake YAMATO, Red Hat K.K., + Copyright (C) 1996-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches. + Copyright (C) 2007-2023 by David Turner. + Copyright (C) 2022-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. + Copyright (C) 2007-2023 by Rahul Bhalerao , . + Copyright (C) 2008-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. + Copyright (C) 2013-2023 by Google, Inc. + Copyright (C) 2019-2023 by Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. + Copyright (C) 2009-2023 by Oran Agra and Mickey Gabel. + Copyright (C) 2018-2023 by David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. + Copyright (C) 2004-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. . - --- begin of LICENSE --- . - JLine License + The FreeType Project LICENSE + ---------------------------- . + 2006-Jan-27 . - Copyright (c) 2002-2018, the original author or authors. - All rights reserved. + Copyright 1996-2002, 2006 by + David Turner, Robert Wilhelm, and Werner Lemberg . - https://opensource.org/licenses/BSD-3-Clause . - 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. + Introduction + ============ . - 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. + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. . - Neither the name of JLine nor the names of its contributors - may be used to endorse or promote products derived from this - software without specific prior written permission. + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. . - 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 license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: . + o We don't promise that this software works. However, we will be + interested in any kind of bug reports. (`as is' distribution) . - 4th Party Dependency - ============= - org.fusesource.jansi version 2.4.0 - org.apache.sshd 2.9.2 - org.apache.felix.gogo.runtime 1.1.6 - org.apache.felix.gogo.jline 1.1.8 - ============= - Apache 2.0 License: Refer to the copy under /usr/share/common-licenses + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) . + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you have used the + FreeType code. (`credits') . - ============= - juniversalchardet + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering The FreeType Project and + assume no liability related to The FreeType Project. . - The library is subject to the Mozilla Public License Version 1.1. . - Alternatively, the library may be used under the terms of either the GNU General Public License Version 2 or later, or the GNU Lesser General Public License 2.1 or later. + Finally, many people asked us for a preferred form for a + credit/disclaimer to use in compliance with this license. We thus + encourage you to use the following text: . - ================ + """ + Portions of this software are copyright © The FreeType + Project (www.freetype.org). All rights reserved. + """ . - slf4j + Please replace with the value from the FreeType version you + actually use. . - SLF4J source code and binaries are distributed under the MIT license. . + Legal Terms + =========== . - Copyright (c) 2004-2023 QOS.ch - All rights reserved. + 0. Definitions + -------------- . - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType Project', be they named as alpha, + beta or final release. . - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + This license applies to all files distributed in the original + FreeType Project, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. . - These terms are identical to those of the MIT License, also called the X License - or the X11 License, which is a simple, permissive non-copyleft free software license. - It is deemed compatible with virtually all types of licenses, commercial or otherwise. - In particular, the Free Software Foundation has declared it compatible with GNU GPL. - It is also known to be approved by the Apache Software Foundation as compatible with - Apache Software License. + The FreeType Project is copyright (C) 1996-2000 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. . + 1. No Warranty + -------------- . + THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. . - --- end of LICENSE --- + 2. Redistribution + ----------------- . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to Unicode Common Local Data Repository (CLDR) v43, - which may be included with JRE 21, JDK 21 and OpenJDK 21 + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the FreeType Project (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: . - --- begin of LICENSE --- + o Redistribution of source code must retain this license file + (`FTL.TXT') unaltered; any additions, deletions or changes to + the original files must be clearly indicated in accompanying + documentation. The copyright notices of the unaltered, + original files must be preserved in all copies of source + files. . - CLDR License + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. . + These conditions apply to any software derived from or based on + the FreeType Project, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. . + 3. Advertising + -------------- . - UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE + Neither the FreeType authors and contributors nor you shall use + the name of the other for commercial, advertising, or promotional + purposes without specific prior written permission. . - See Terms of Use - for definitions of Unicode Inc.’s Data Files and Software. + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. . - NOTICE TO USER: Carefully read the following legal agreement. - BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S - DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), - YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE - TERMS AND CONDITIONS OF THIS AGREEMENT. - IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE - THE DATA FILES OR SOFTWARE. + As you have not signed this license, you are not required to + accept it. However, as the FreeType Project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + Project, you indicate that you understand and accept all the terms + of this license. . - COPYRIGHT AND PERMISSION NOTICE + 4. Contacts + ----------- . - Copyright © 1991-2022 Unicode, Inc. All rights reserved. - Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + There are two mailing lists related to FreeType: . - Permission is hereby granted, free of charge, to any person obtaining - a copy of the Unicode data files and any associated documentation - (the "Data Files") or Unicode software and any associated documentation - (the "Software") to deal in the Data Files or Software - without restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, and/or sell copies of - the Data Files or Software, and to permit persons to whom the Data Files - or Software are furnished to do so, provided that either - (a) this copyright and permission notice appear with all copies - of the Data Files or Software, or - (b) this copyright and permission notice appear in associated - Documentation. + o freetype@nongnu.org . - THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS - NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 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 THE DATA FILES OR SOFTWARE. + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. . - Except as contained in this notice, the name of a copyright holder - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in these Data Files or Software without prior - written authorization of the copyright holder. + o freetype-devel@nongnu.org . + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. . + Our home page can be found at . - ------------------------------------------------------------ Terms of Use --------------------------------------------------------------- + https://www.freetype.org . . - Unicode® Copyright and Terms of Use . - For the general privacy policy governing access to this site, see the Unicode Privacy Policy. + GPL v2: Refer to the copy under /usr/share/common-licenses . - Unicode Copyright - Copyright © 1991-2023 Unicode, Inc. All rights reserved. - Definitions + Additional Freetype Attributions . - 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/ + --------------------------------- + The below license applies to the following files: + libfreetype/src/psaux/psarrst.c + libfreetype/src/psaux/psarrst.h + libfreetype/src/psaux/psblues.c + libfreetype/src/psaux/psblues.h + libfreetype/src/psaux/pserror.c + libfreetype/src/psaux/pserror.h + libfreetype/src/psaux/psfixed.h + libfreetype/src/psaux/psfont.c + libfreetype/src/psaux/psfont.h + libfreetype/src/psaux/psft.c + libfreetype/src/psaux/psft.h + libfreetype/src/psaux/psglue.h + libfreetype/src/psaux/pshints.c + libfreetype/src/psaux/pshints.h + libfreetype/src/psaux/psintrp.c + libfreetype/src/psaux/psintrp.h + libfreetype/src/psaux/psread.c + libfreetype/src/psaux/psread.h + libfreetype/src/psaux/psstack.c + libfreetype/src/psaux/psstack.h + libfreetype/src/psaux/pstypes.h . - 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/ + Copyright 2006-2014 Adobe Systems Incorporated. . - 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. + This software, and all works of authorship, whether in source or + object code form as indicated by the copyright notice(s) included + herein (collectively, the "Work") is made available, and may only be + used, modified, and distributed under the FreeType Project License, + LICENSE.TXT. Additionally, subject to the terms and conditions of the + FreeType Project License, each contributor to the Work hereby grants + to any individual or legal entity exercising permissions granted by + the FreeType Project License and this section (hereafter, "You" or + "Your") a perpetual, worldwide, non-exclusive, no-charge, + royalty-free, irrevocable (except as stated in this section) patent + license to make, have made, use, offer to sell, sell, import, and + otherwise transfer the Work, where such license applies only to those + patent claims licensable by such contributor that are necessarily + infringed by their contribution(s) alone or by combination of their + contribution(s) with the Work to which such contribution(s) was + submitted. If You institute patent litigation against any entity + (including a cross-claim or counterclaim in a lawsuit) alleging that + the Work or a contribution incorporated within the Work constitutes + direct or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate as of + the date such litigation is filed. . + By using, modifying, or distributing the Work you indicate that you + have read and understood the terms and conditions of the + FreeType Project License as well as those provided in this section, + and you accept them fully. . . - --- end of LICENSE --- . - ------------------------------------------------------------------------------ - %% This notice is provided with respect to Thai Dictionary, - which may be included with JRE 21, JDK 21 and OpenJDK 21 . - --- begin of LICENSE --- + MIT License . - Thai Dictionary License . + --------------------------------- + The below license applies to the following files: + libfreetype/include/freetype/internal/fthash.h + libfreetype/src/base/fthash.c . - Copyright (C) 1982 The Royal Institute, Thai Royal Government. + Copyright 2000 Computing Research Labs, New Mexico State University + Copyright 2001-2015 . - Copyright (C) 1998 National Electronics and Computer Technology Center, - National Science and Technology Development Agency, - Ministry of Science Technology and Environment, - Thai Royal Government. + Francesco Zappa Nardelli . - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: . - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE. + . . . . @@ -2729,20 +2251,6 @@ --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to Eastman Kodak Company: Portions of color management and imaging software, - which may be included with JRE 21, JDK 21 and OpenJDK 21 - . - --- begin of LICENSE --- - . - Eastman Kodak Notice - . - Portions Copyright Eastman Kodak Company 1991-2003 - . - . - . - --- end of LICENSE --- - . - ------------------------------------------------------------------------------ %% This notice is provided with respect to Mesa 3-D Graphics Library v21.0.3, which may be included with JRE 21, JDK 21 and OpenJDK 21 . @@ -2884,402 +2392,605 @@ --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to The FreeType Project: Freetype v2.13.0, + %% This notice is provided with respect to PipeWire 0.3.68, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . + PipeWire license: . - FreeType Notice + All PipeWire header files are licensed under the MIT License: . . - FreeType comes with two licenses from which you can choose the one - which fits your needs best. . - The FreeType License (FTL) is the most commonly used one. It is - a BSD-style license with a credit clause and thus compatible with - the GNU Public License (GPL) version 3, but not with the - GPL version 2. + Copyright © 2018-2023 Wim Taymans . - The GNU General Public License (GPL), version 2. Use it for all - projects which use the GPLv2 also, or which need a license - compatible to the GPLv2. + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: . + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. . - FreeType License . + The below copyright applies to the following files: . - Copyright (C) 1996-2023 by David Turner, Robert Wilhelm, and Werner Lemberg. - Copyright (C) 2007-2023 by Dereg Clegg and Michael Toftdal. - Copyright (C) 1996-2023 by Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. - Copyright (C) 2022-2023 by David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and - Copyright (C) 2004-2023 by Masatake YAMATO and Redhat K.K. - Copyright (C) 2007-2023 by Derek Clegg and Michael Toftdal. - Copyright (C) 2003-2023 by Masatake YAMATO, Red Hat K.K., - Copyright (C) 1996-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches. - Copyright (C) 2007-2023 by David Turner. - Copyright (C) 2022-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. - Copyright (C) 2007-2023 by Rahul Bhalerao , . - Copyright (C) 2008-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. - Copyright (C) 2013-2023 by Google, Inc. - Copyright (C) 2019-2023 by Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. - Copyright (C) 2009-2023 by Oran Agra and Mickey Gabel. - Copyright (C) 2018-2023 by David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. - Copyright (C) 2004-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. + spa/include/spa/monitor/type-info.h . + Copyright © 2021 Collabora Ltd. . - The FreeType Project LICENSE - ---------------------------- . - 2006-Jan-27 + spa/include/spa/utils/string.h . - Copyright 1996-2002, 2006 by - David Turner, Robert Wilhelm, and Werner Lemberg + Copyright © 2021 Red Hat, Inc. . . + --- end of LICENSE --- . - Introduction - ============ + ------------------------------------------------------------------------------ + %% This notice is provided with respect to xwd v1.0.7, + which may be included with JRE 21, JDK 21 and OpenJDK 21 . - The FreeType Project is distributed in several archive packages; - some of them may contain, in addition to the FreeType font engine, - various tools and contributions which rely on, or relate to, the - FreeType Project. + --- begin of LICENSE --- . - This license applies to all files found in such packages, and - which do not fall under their own explicit license. The license - affects thus the FreeType font engine, the test programs, - documentation and makefiles, at the very least. + xwd utility . - This license was inspired by the BSD, Artistic, and IJG - (Independent JPEG Group) licenses, which all encourage inclusion - and use of free software in commercial and freeware products - alike. As a consequence, its main points are that: . - o We don't promise that this software works. However, we will be - interested in any kind of bug reports. (`as is' distribution) + This is the copyright for the files in src/java.desktop/unix/native/libawt_xawt: + list.h, multiVis.h, wsutils.h, list.c, multiVis.c . - o You can use this software for whatever you want, in parts or - full form, without having to pay us. (`royalty-free' usage) + Copyright 1994 Hewlett-Packard Co. + Copyright 1996, 1998 The Open Group . - o You may not pretend that you wrote this software. If you use - it, or only parts of it, in a program, you must acknowledge - somewhere in your documentation that you have used the - FreeType code. (`credits') + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. . - We specifically permit and encourage the inclusion of this - software, with or without modifications, in commercial products. - We disclaim all warranties covering The FreeType Project and - assume no liability related to The FreeType Project. + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. . - Finally, many people asked us for a preferred form for a - credit/disclaimer to use in compliance with this license. We thus - encourage you to use the following text: + Except as contained in this notice, the name of The Open Group shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from The Open Group. . - """ - Portions of this software are copyright © The FreeType - Project (www.freetype.org). All rights reserved. - """ . - Please replace with the value from the FreeType version you - actually use. . + --- end of LICENSE --- . - Legal Terms - =========== + ------------------------------------------------------------------------------ + %% This notice is provided with respect to Apache Commons Byte Code Engineering Library (BCEL) Version 6.7.0, + which may be included with JRE 21, JDK 21 and OpenJDK 21 . - 0. Definitions - -------------- + --- begin of LICENSE --- . - Throughout this license, the terms `package', `FreeType Project', - and `FreeType archive' refer to the set of files originally - distributed by the authors (David Turner, Robert Wilhelm, and - Werner Lemberg) as the `FreeType Project', be they named as alpha, - beta or final release. + Apache Commons BCEL Notice . - `You' refers to the licensee, or person using the project, where - `using' is a generic term including compiling the project's source - code as well as linking it to form a `program' or `executable'. - This program is referred to as `a program using the FreeType - engine'. . - This license applies to all files distributed in the original - FreeType Project, including all source code, binaries and - documentation, unless otherwise stated in the file in its - original, unmodified form as distributed in the original archive. - If you are unsure whether or not a particular file is covered by - this license, you must contact us to verify this. + Apache Commons BCEL + Copyright 2004-2022 The Apache Software Foundation . - The FreeType Project is copyright (C) 1996-2000 by David Turner, - Robert Wilhelm, and Werner Lemberg. All rights reserved except as - specified below. + This product includes software developed at + The Apache Software Foundation (https://www.apache.org/). . - 1. No Warranty - -------------- . - THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY - KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO - USE, OF THE FREETYPE PROJECT. . - 2. Redistribution - ----------------- + Apache 2.0 License: Refer to the copy under /usr/share/common-licenses . - This license grants a worldwide, royalty-free, perpetual and - irrevocable right and license to use, execute, perform, compile, - display, copy, create derivative works of, distribute and - sublicense the FreeType Project (in both source and object code - forms) and derivative works thereof for any purpose; and to - authorize others to exercise some or all of the rights granted - herein, subject to the following conditions: . - o Redistribution of source code must retain this license file - (`FTL.TXT') unaltered; any additions, deletions or changes to - the original files must be clearly indicated in accompanying - documentation. The copyright notices of the unaltered, - original files must be preserved in all copies of source - files. + --- end of LICENSE --- . - o Redistribution in binary form must provide a disclaimer that - states that the software is based in part of the work of the - FreeType Team, in the distribution documentation. We also - encourage you to put an URL to the FreeType web page in your - documentation, though this isn't mandatory. + ------------------------------------------------------------------------------ + %% This notice is provided with respect to DOM Level 3 Core Specification v1.0, + which may be included with JRE 21, JDK 21 and OpenJDK 21 . - These conditions apply to any software derived from or based on - the FreeType Project, not just the unmodified files. If you use - our work, you must acknowledge us. However, no fee need be paid - to us. + --- begin of LICENSE --- . - 3. Advertising - -------------- + W3C Software Notice . - Neither the FreeType authors and contributors nor you shall use - the name of the other for commercial, advertising, or promotional - purposes without specific prior written permission. + Copyright © 2004 World Wide Web Consortium, (Massachusetts Institute of Technology, + European Research Consortium for Informatics and Mathematics, Keio University). + All Rights Reserved. . - We suggest, but do not require, that you use one or more of the - following phrases to refer to this software in your documentation - or advertising materials: `FreeType Project', `FreeType Engine', - `FreeType library', or `FreeType Distribution'. + The DOM bindings are published under the W3C Software Copyright Notice and License. + The software license requires "Notice of any changes or modifications to the W3C + files, including the date changes were made." Consequently, modified versions of + the DOM bindings must document that they do not conform to the W3C standard; in the + case of the IDL definitions, the pragma prefix can no longer be 'w3c.org'; in the + case of the Java language binding, the package names can no longer be in the + 'org.w3c' package. . - As you have not signed this license, you are not required to - accept it. However, as the FreeType Project is copyrighted - material, only this license, or another one contracted with the - authors, grants you the right to use, distribute, and modify it. - Therefore, by using, distributing, or modifying the FreeType - Project, you indicate that you understand and accept all the terms - of this license. . - 4. Contacts - ----------- + W3C License . - There are two mailing lists related to FreeType: . - o freetype@nongnu.org + W3C SOFTWARE NOTICE AND LICENSE . - Discusses general use and applications of FreeType, as well as - future and wanted additions to the library and distribution. - If you are looking for support, start in this list if you - haven't found anything to help you in the documentation. + http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 . - o freetype-devel@nongnu.org + This work (and included software, documentation such as READMEs, or other + related items) is being provided by the copyright holders under the following + license. By obtaining, using and/or copying this work, you (the licensee) + agree that you have read, understood, and will comply with the following terms + and conditions. . - Discusses bugs, as well as engine internals, design issues, - specific licenses, porting, etc. + Permission to copy, modify, and distribute this software and its + documentation, with or without modification, for any purpose and without fee + or royalty is hereby granted, provided that you include the following on ALL + copies of the software and documentation or portions thereof, including + modifications: . - Our home page can be found at + 1.The full text of this NOTICE in a location viewable to users of the + redistributed or derivative work. . - https://www.freetype.org + 2.Any pre-existing intellectual property disclaimers, notices, or terms and + conditions. If none exist, the W3C Software Short Notice should be included + (hypertext is preferred, text is permitted) within the body of any + redistributed or derivative code. . + 3.Notice of any changes or modifications to the files, including the date + changes were made. (We recommend you provide URIs to the location from + which the code is derived.) . + THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS + MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR + PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY + THIRD PARTY PATENTS,COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. . - GPL v2: Refer to the copy under /usr/share/common-licenses + COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL + OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR + DOCUMENTATION. The name and trademarks of copyright holders may NOT be used + in advertising or publicity pertaining to the software without specific, + written prior permission. Title to copyright in this software and any + associated documentation will at all times remain with copyright holders. . - Additional Freetype Attributions + ____________________________________ . + This formulation of W3C's notice and license became active on December 31 + 2002. This version removes the copyright ownership notice such that this + license can be used with materials other than those owned by the W3C, reflects + that ERCIM is now a host of the W3C, includes references to this specific + dated version of the license, and removes the ambiguous grant of "use". + Otherwise, this version is the same as the previous version and is written so + as to preserve the Free Software Foundation's assessment of GPL compatibility + and OSI's certification under the Open Source Definition. Please see our + Copyright FAQ for common questions about using materials from our site, + including specific terms and conditions for packages like libwww, Amaya, and + Jigsaw. Other questions about this notice can be directed to + site-policy@w3.org. . - --------------------------------- - The below license applies to the following files: - libfreetype/src/psaux/psarrst.c - libfreetype/src/psaux/psarrst.h - libfreetype/src/psaux/psblues.c - libfreetype/src/psaux/psblues.h - libfreetype/src/psaux/pserror.c - libfreetype/src/psaux/pserror.h - libfreetype/src/psaux/psfixed.h - libfreetype/src/psaux/psfont.c - libfreetype/src/psaux/psfont.h - libfreetype/src/psaux/psft.c - libfreetype/src/psaux/psft.h - libfreetype/src/psaux/psglue.h - libfreetype/src/psaux/pshints.c - libfreetype/src/psaux/pshints.h - libfreetype/src/psaux/psintrp.c - libfreetype/src/psaux/psintrp.h - libfreetype/src/psaux/psread.c - libfreetype/src/psaux/psread.h - libfreetype/src/psaux/psstack.c - libfreetype/src/psaux/psstack.h - libfreetype/src/psaux/pstypes.h . - Copyright 2006-2014 Adobe Systems Incorporated. . - This software, and all works of authorship, whether in source or - object code form as indicated by the copyright notice(s) included - herein (collectively, the "Work") is made available, and may only be - used, modified, and distributed under the FreeType Project License, - LICENSE.TXT. Additionally, subject to the terms and conditions of the - FreeType Project License, each contributor to the Work hereby grants - to any individual or legal entity exercising permissions granted by - the FreeType Project License and this section (hereafter, "You" or - "Your") a perpetual, worldwide, non-exclusive, no-charge, - royalty-free, irrevocable (except as stated in this section) patent - license to make, have made, use, offer to sell, sell, import, and - otherwise transfer the Work, where such license applies only to those - patent claims licensable by such contributor that are necessarily - infringed by their contribution(s) alone or by combination of their - contribution(s) with the Work to which such contribution(s) was - submitted. If You institute patent litigation against any entity - (including a cross-claim or counterclaim in a lawsuit) alleging that - the Work or a contribution incorporated within the Work constitutes - direct or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate as of - the date such litigation is filed. + --- end of LICENSE --- . - By using, modifying, or distributing the Work you indicate that you - have read and understood the terms and conditions of the - FreeType Project License as well as those provided in this section, - and you accept them fully. + ------------------------------------------------------------------------------ + %% This notice is provided with respect to CUP Parser Generator for Java v 0.11b, + which may be included with JRE 21, JDK 21 and OpenJDK 21 . + --- begin of LICENSE --- . + CUP Parser Generator License . . - MIT License + Copyright 1996-2015 by Scott Hudson, Frank Flannery, C. Scott Ananian, Michael Petter . + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both + the copyright notice and this permission notice and warranty disclaimer + appear in supporting documentation, and that the names of the authors or + their employers not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior permission. . - --------------------------------- - The below license applies to the following files: - libfreetype/include/freetype/internal/fthash.h - libfreetype/src/base/fthash.c + The authors and their employers disclaim all warranties with regard to + this software, including all implied warranties of merchantability and + fitness. In no event shall the authors or their employers be liable for + any special, 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. . - Copyright 2000 Computing Research Labs, New Mexico State University - Copyright 2001-2015 + --- . - Francesco Zappa Nardelli + This is an open source license. It is also GPL-Compatible (see entry for + "Standard ML of New Jersey"). The portions of CUP output which are hard-coded + into the CUP source code are (naturally) covered by this same license, as is + the CUP runtime code linked with the generated parser. . - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: . - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - THE USE OR OTHER DEALINGS IN THE SOFTWARE. + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to Apache Xalan v2.7.2, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + Apache Xalan Notice + . + . + ====================================================================================== + == NOTICE file corresponding to the section 4d of the Apache License, Version 2.0, == + == in this case for the Apache Xalan distribution. == + ====================================================================================== + . + This product includes software developed by + The Apache Software Foundation (http://www.apache.org/). + . + Specifically, we only include the XSLTC portion of the source from the Xalan distribution. + The Xalan project has two processors: an interpretive one (Xalan Interpretive) and a + compiled one (The XSLT Compiler (XSLTC)). We *only* use the XSLTC part of Xalan; We use + the source from the packages that are part of the XSLTC sources. + . + Portions of this software was originally based on the following: + . + - software copyright (c) 1999-2002, Lotus Development Corporation., http://www.lotus.com. + - software copyright (c) 2001-2002, Sun Microsystems., http://www.sun.com. + - software copyright (c) 2003, IBM Corporation., http://www.ibm.com. + - voluntary contributions made by Ovidiu Predescu (ovidiu@cup.hp.com) on behalf of the + Apache Software Foundation and was originally developed at Hewlett Packard Company. . . . + Apache 2.0 License: Refer to the copy under /usr/share/common-licenses + . . --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to xwd v1.0.7, + %% This notice is provided with respect to Apache Xerces v2.12.2, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . - xwd utility + Apache Xerces Notice . + ========================================================================= + == NOTICE file corresponding to section 4(d) of the Apache License, == + == Version 2.0, in this case for the Apache Xerces Java distribution. == + ========================================================================= . - This is the copyright for the files in src/java.desktop/unix/native/libawt_xawt: - list.h, multiVis.h, wsutils.h, list.c, multiVis.c + Apache Xerces Java + Copyright 1999-2022 The Apache Software Foundation . - Copyright 1994 Hewlett-Packard Co. - Copyright 1996, 1998 The Open Group + This product includes software developed at + The Apache Software Foundation (http://www.apache.org/). . - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. + Portions of this software were originally based on the following: + - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. + - software copyright (c) 1999, Sun Microsystems., http://www.sun.com. + - voluntary contributions made by Paul Eng on behalf of the + Apache Software Foundation that were originally developed at iClick, Inc., + software copyright (c) 1999. . - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. + Apache 2.0 License: Refer to the copy under /usr/share/common-licenses . - Except as contained in this notice, the name of The Open Group shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from The Open Group. + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to Apache Santuario v3.0.2, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + Apache 2.0 License: Refer to the copy under /usr/share/common-licenses + . + Apache Santuario Notice . . + Apache Santuario - XML Security for Java + Copyright 1999-2023 The Apache Software Foundation + . + This product includes software developed at + The Apache Software Foundation (http://www.apache.org/). + . + It was originally based on software copyright (c) 2001, Institute for + Data Communications Systems, . + . + The development of this software was partly funded by the European + Commission in the project in the ISIS Programme. + . + This product contains software that is + copyright (c) 2021, Oracle and/or its affiliates. + . . --- end of LICENSE --- . ------------------------------------------------------------------------------ - %% This notice is provided with respect to PipeWire 0.3.68, + %% This notice is provided with respect to OASIS PKCS #11 Cryptographic Token Interface v3.0, which may be included with JRE 21, JDK 21 and OpenJDK 21 . --- begin of LICENSE --- . - PipeWire license: + OASIS PKCS #11 Cryptographic Token Interface License . - All PipeWire header files are licensed under the MIT License: . + Copyright © OASIS Open 2020. All Rights Reserved. . + All capitalized terms in the following text have the meanings + assigned to them in the OASIS Intellectual Property Rights Policy (the + "OASIS IPR Policy"). The full Policy may be found at the OASIS website: + [http://www.oasis-open.org/policies-guidelines/ipr] . - Copyright © 2018-2023 Wim Taymans + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it or + assist in its implementation may be prepared, copied, published, and + distributed, in whole or in part, without restriction of any kind, + provided that the above copyright notice and this section are included + on all such copies and derivative works. However, this document itself + may not be modified in any way, including by removing the copyright + notice or references to OASIS, except as needed for the purpose of + developing any document or deliverable produced by an OASIS Technical + Committee (in which case the rules applicable to copyrights, as set + forth in the OASIS IPR Policy, must be followed) or as required to + translate it into languages other than English. . - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: + The limited permissions granted above are perpetual and will not be + revoked by OASIS or its successors or assigns. . - The above copyright notice and this permission notice (including the next - paragraph) shall be included in all copies or substantial portions of the - Software. + This document and the information contained herein is provided on an + "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. OASIS + AND ITS MEMBERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THIS DOCUMENT OR ANY + PART THEREOF. . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. + [OASIS requests that any OASIS Party or any other party that + believes it has patent claims that would necessarily be infringed by + implementations of this OASIS Standards Final Deliverable, to notify + OASIS TC Administrator and provide an indication of its willingness to + grant patent licenses to such patent claims in a manner consistent with + the IPR Mode of the OASIS Technical Committee that produced this + deliverable.] . + [OASIS invites any party to contact the OASIS TC Administrator if it + is aware of a claim of ownership of any patent claims that would + necessarily be infringed by implementations of this OASIS Standards + Final Deliverable by a patent holder that is not willing to provide a + license to such patent claims in a manner consistent with the IPR Mode + of the OASIS Technical Committee that produced this OASIS Standards + Final Deliverable. OASIS may include such claims on its website, but + disclaims any obligation to do so.] . - The below copyright applies to the following files: + [OASIS takes no position regarding the validity or scope of any + intellectual property or other rights that might be claimed to pertain + to the implementation or use of the technology described in this OASIS + Standards Final Deliverable or the extent to which any license under + such rights might or might not be available; neither does it represent + that it has made any effort to identify any such rights. Information on + OASIS' procedures with respect to rights in any document or deliverable + produced by an OASIS Technical Committee can be found on the OASIS + website. Copies of claims of rights made available for publication and + any assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this OASIS Standards + Final Deliverable, can be obtained from the OASIS TC Administrator. + OASIS makes no representation that any information or list of + intellectual property rights will at any time be complete, or that any + claims in such list are, in fact, Essential Claims.] . - spa/include/spa/monitor/type-info.h . - Copyright © 2021 Collabora Ltd. . + --- end of LICENSE --- . - spa/include/spa/utils/string.h + ------------------------------------------------------------------------------ + %% This notice is provided with respect to IAIK (Institute for Applied Information Processing and Communication) PKCS#11 wrapper files v1, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + IAIK License + . + . + Copyright (c) 2002 Graz University of Technology. 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. + . + 3. The end-user documentation included with the redistribution, if any, must + include the following acknowledgment: + . + "This product includes software developed by IAIK of Graz University of + Technology." + . + Alternately, this acknowledgment may appear in the software itself, if and + wherever such third-party acknowledgments normally appear. + . + 4. The names "Graz University of Technology" and "IAIK of Graz University of + Technology" must not be used to endorse or promote products derived from this + software without prior written permission. + . + 5. Products derived from this software may not be called "IAIK PKCS Wrapper", + nor may "IAIK" appear in their name, without prior written permission of + Graz University of Technology. + . + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED 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 + LICENSOR 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. + . + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to Dynalink v.5, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + Dynalink License + . + . + Copyright (c) 2009-2013, Attila Szegedi + . + 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 the copyright holder nor the names of + 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 COPYRIGHT HOLDER + 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. + . + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to JLine v3.22.0, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + JLine License + . + . + Copyright (c) 2002-2018, the original author or authors. + All rights reserved. + . + https://opensource.org/licenses/BSD-3-Clause + . + 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 JLine 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. + . + . + 4th Party Dependency + ============= + org.fusesource.jansi version 2.4.0 + org.apache.sshd 2.9.2 + org.apache.felix.gogo.runtime 1.1.6 + org.apache.felix.gogo.jline 1.1.8 + ============= + Apache 2.0 License: Refer to the copy under /usr/share/common-licenses + . + . + ============= + juniversalchardet + . + The library is subject to the Mozilla Public License Version 1.1. + . + Alternatively, the library may be used under the terms of either the GNU General Public License Version 2 or later, or the GNU Lesser General Public License 2.1 or later. + . + ================ + . + slf4j + . + SLF4J source code and binaries are distributed under the MIT license. + . + . + Copyright (c) 2004-2023 QOS.ch + All rights reserved. + . + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + . + These terms are identical to those of the MIT License, also called the X License + or the X11 License, which is a simple, permissive non-copyleft free software license. + It is deemed compatible with virtually all types of licenses, commercial or otherwise. + In particular, the Free Software Foundation has declared it compatible with GNU GPL. + It is also known to be approved by the Apache Software Foundation as compatible with + Apache Software License. . - Copyright © 2021 Red Hat, Inc. . . --- end of LICENSE --- @@ -3316,6 +3027,295 @@ . . . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to jQuery v3.6.1, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + jQuery License + . + jQuery v 3.6.1 + Copyright OpenJS Foundation and other contributors, https://openjsf.org/ + . + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + . + ****************************************** + . + The jQuery JavaScript Library v3.6.1 also includes Sizzle.js + . + Sizzle.js includes the following license: + . + Copyright JS Foundation and other contributors, https://js.foundation/ + . + This software consists of voluntary contributions made by many + individuals. For exact contribution history, see the revision history + available at https://github.com/jquery/sizzle + . + The following license applies to all parts of this software except as + documented below: + . + ==== + . + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + . + ==== + . + All files located in the node_modules and external directories are + externally maintained libraries used by this software which have their + own licenses; we recommend you read them, as their terms may differ from + the terms above. + . + ********************* + . + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to jQuery UI v1.13.2, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + jQuery UI License + . + Copyright jQuery Foundation and other contributors, https://jquery.org/ + . + This software consists of voluntary contributions made by many + individuals. For exact contribution history, see the revision history + available at https://github.com/jquery/jquery-ui + . + The following license applies to all parts of this software except as + documented below: + . + ==== + . + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + . + ==== + . + Copyright and related rights for sample code are waived via CC0. Sample + code is defined as all source code contained within the demos directory. + . + CC0: http://creativecommons.org/publicdomain/zero/1.0/ + . + ==== + . + All files located in the node_modules and external directories are + externally maintained libraries used by this software which have their + own licenses; we recommend you read them, as their terms may differ from + the terms above. + . + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to Unicode Common Local Data Repository (CLDR) v43, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + CLDR License + . + . + . + UNICODE, INC. LICENSE AGREEMENT - 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 + DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), + YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE + TERMS AND CONDITIONS OF THIS AGREEMENT. + IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE + THE DATA FILES OR SOFTWARE. + . + COPYRIGHT AND PERMISSION NOTICE + . + Copyright © 1991-2022 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + . + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Unicode data files and any associated documentation + (the "Data Files") or Unicode software and any associated documentation + (the "Software") to deal in the Data Files or Software + without restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, and/or sell copies of + the Data Files or Software, and to permit persons to whom the Data Files + or Software are furnished to do so, provided that either + (a) this copyright and permission notice appear with all copies + of the Data Files or Software, or + (b) this copyright and permission notice appear in associated + Documentation. + . + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 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 THE DATA FILES OR SOFTWARE. + . + Except as contained in this notice, the name of a copyright holder + shall not be used in advertising or otherwise to promote the sale, + 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-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. + . + . + . + --- end of LICENSE --- + . + ------------------------------------------------------------------------------ + %% This notice is provided with respect to Thai Dictionary, + which may be included with JRE 21, JDK 21 and OpenJDK 21 + . + --- begin of LICENSE --- + . + Thai Dictionary License + . + . + Copyright (C) 1982 The Royal Institute, Thai Royal Government. + . + Copyright (C) 1998 National Electronics and Computer Technology Center, + National Science and Technology Development Agency, + Ministry of Science Technology and Environment, + Thai Royal Government. + . + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + . + . + . --- end of LICENSE --- . ------------------------------------------------------------------------------ diff -Nru openjdk-21-21.0.1+12/debian/copyright-generator/copyright-gen.py openjdk-21-21.0.2+13/debian/copyright-generator/copyright-gen.py --- openjdk-21-21.0.1+12/debian/copyright-generator/copyright-gen.py 2023-11-23 19:34:46.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/copyright-generator/copyright-gen.py 2024-01-17 12:14:57.000000000 +0000 @@ -23,6 +23,7 @@ import textwrap version = ""; +needs_cleanup = False packaged_by = "Matthias Klose "; common_licenses = {}; @@ -96,9 +97,9 @@ exclude_licenses = ["zlib.md", "pcsclite.md", "giflib.md", "libpng.md", "jpeg.md"] def print_field(name, single_line, value): - print(name + ": ", end="") + print(name + ":", end="") if (single_line): - print(value) + print(" " + value) else: print("\n" + value) @@ -106,12 +107,12 @@ print_field("Format", True, format) print_field("Files-Excluded", False, files_excluded) print_field("Source", True, source) - print_field("Comment", True, comment) + print_field("Comment", False, comment) print() # an empty line def print_file_stanza(files, copyrights, license, comments): print_field("Files", True, files) - print_field("Copyrights", False, copyrights) + print_field("Copyright", False, copyrights) print_field("License", True, license) if (comments is not None and len(comments) != 0): print_field("Comments", True, comments) @@ -122,8 +123,7 @@ def generate_comment_str(): upstream_authors_str = "\n ".join(upstream_authors) - return f""" - Upstream Authors: + return f""" Upstream Authors: OpenJDK: {upstream_authors_str} Packaged by: @@ -132,7 +132,7 @@ def generate_header_stanza(): format = "https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/" excluded = generate_excluded_files_str() - source = "https://github.com/openjdk/jdk" + source = "https://github.com/openjdk/jdk21u" comment = generate_comment_str() print_header_stanza(format, excluded, source, comment) @@ -166,6 +166,7 @@ which may be included with JRE {version}, JDK {version} and OpenJDK {version}""" def gen_license_text(license): + print("Gathering license content for " + license, file=sys.stderr) component, content = get_content(license) component = component.split("## ")[1].rstrip("\n"); return f""" @@ -178,7 +179,7 @@ ------------------------------------------------------------------------------""" -def get_legal_dirs(path): +def gather_legal_dirs(path): legal_dirs = [] for root, dirs, files in os.walk(path): if "legal" in dirs and (root.endswith("share") or root.endswith("unix")): @@ -186,33 +187,65 @@ return legal_dirs def gather_licenses(module): - legal_dirs = get_legal_dirs(module) + legal_dirs = gather_legal_dirs(module) licenses_text = "" - for dir in legal_dirs: - licenses = os.scandir(dir) - for license in licenses: - if not license.name in exclude_licenses: - licenses_text += gen_license_text(license.path) + for dir in sorted(legal_dirs): + licenses = os.listdir(dir) + for license in sorted(licenses): + if not license in exclude_licenses: + licenses_text += gen_license_text(dir + "/" + license) return licenses_text def gather_modules_licenses(srcdir): licenses = "" - modules = os.scandir(srcdir) - for module in modules: - licenses += gather_licenses(module) + modules = os.listdir(srcdir) + for module in sorted(modules): + licenses += gather_licenses(srcdir + "/" + module) return licenses -def find_directory(prefix): - for file in os.scandir(): +def find_directory(prefix, path = '.'): + for file in os.scandir(path): if file.is_dir() and file.name.startswith(prefix): return file.path - + +def search_source_rootdir(level, path = '.'): + # The user might have already pulled the source package. + # Search for a downloaded package at three levels + # - openjdk + # - openjdk/debian + # - openjdk/debian/copyright-generator + # if one none found, download the source package + rootdir = find_directory(f"openjdk-{version}", path) + if rootdir is not None: + return rootdir + + match level: + case 0: + path = "./debian" + level= level + 1 + case 1: + path = "./debian/copyright-generator" + level = level + 1 + case 2: + print("No source package found. Downloading...", file = sys.stderr) + os.system(f"pull-debian-source openjdk-{version} > /dev/null 2>&1") + needs_cleanup = True + return find_directory(f"openjdk-{version}") + case _: + print("Irrecoverable error while searching for source package") + exit(1) + + return search_source_rootdir(level, path) + def generate_copyright(): - os.system(f"pull-debian-source openjdk-{version} > /dev/null 2>&1") - rootdir = find_directory(f"openjdk-{version}") + rootdir = search_source_rootdir(0) + if rootdir is None: + print("No source package found. Download also failed. Aborting.") + exit(2) + print(f"Using the source package at {rootdir}", file = sys.stderr) srcdir = f"{rootdir}/src"; - os.system(f"/bin/sh strip-common-licenses.sh {rootdir} {version}") + os.system(f"/bin/sh ./debian/copyright-generator/strip-common-licenses.sh {rootdir} {version}") generate_header_stanza(); licenses = f"""GPL with Classpath exception @@ -229,24 +262,27 @@ print_file_stanza("*", " " + "\n ".join(openjdk_copyrights), fill_with_dots_and_indent(licenses), "") if (version != "11"): - print(open("bundled-stanzas").read()) - print(open("debian-stanzas").read()) + print(open("./debian/copyright-generator/bundled-stanzas").read()) + print(open("./debian/copyright-generator/debian-stanzas").read()) # clean-up - os.system(f"rm -rf {rootdir} *.debian.tar.xz *.orig.tar.xz *.dsc *googletest.tar.xz"); + if needs_cleanup: + os.system(f"rm -rf *.debian.tar.xz *.orig.tar.xz *.dsc *googletest.tar.xz"); def main(): global version + sys.stdout = open('./debian/copyright', 'w') + supported_versions = ["11", "17", "21", "22", "23"] if (len(sys.argv) >= 1): version = sys.argv[1] if version == "" or version == "--help" or version == "-help" or version == "help": - print("Usage:\ncopyright-gen.py > ../copyright") - print("version - 11 | 17 | 21 | 22") - print("Note: this script must be run from the `debian/copyright-generator` directory") - elif version == "11" or version == "17" or version == "21" or version == "22": + print("Usage:\ndebian/copyright-generator/copyright-gen.py ", file=sys.stderr) + print("version - 11 | 17 | 21 | 22 | 23", file=sys.stderr) + + elif version in supported_versions: generate_copyright() else: print("Version not supported.") diff -Nru openjdk-21-21.0.1+12/debian/patches/arch-add-ports.diff openjdk-21-21.0.2+13/debian/patches/arch-add-ports.diff --- openjdk-21-21.0.1+12/debian/patches/arch-add-ports.diff 2023-10-23 06:32:18.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/patches/arch-add-ports.diff 2024-01-17 12:14:57.000000000 +0000 @@ -1,37 +1,20 @@ --- a/src/java.base/share/classes/jdk/internal/util/Architecture.java +++ b/src/java.base/share/classes/jdk/internal/util/Architecture.java -@@ -42,6 +42,14 @@ public enum Architecture { - LOONGARCH64, - S390, - PPC64, -+ ALPHA, -+ ARC, -+ HPPA, -+ IA64, -+ M68K, -+ SH, -+ X32, -+ PPC, - MIPSEL, - MIPS64EL - ; -@@ -89,6 +97,15 @@ public enum Architecture { - } - - /** -+ * {@return {@code true} if the current architecture is PPC} -+ * Use {@link #isLittleEndian()} to determine big or little endian. -+ */ -+ @ForceInline -+ public static boolean isPPC() { -+ return PlatformProps.TARGET_ARCH_IS_PPC; -+ } -+ -+ /** - * {@return {@code true} if the current architecture is PPC64} - * Use {@link #isLittleEndian()} to determine big or little endian. - */ -@@ -98,6 +115,69 @@ public enum Architecture { +@@ -46,6 +46,13 @@ public enum Architecture { + LOONGARCH64(64, ByteOrder.LITTLE_ENDIAN), + MIPSEL(32, ByteOrder.LITTLE_ENDIAN), + MIPS64EL(64, ByteOrder.LITTLE_ENDIAN), ++ ALPHA(64, ByteOrder.LITTLE_ENDIAN), ++ ARC(32, ByteOrder.LITTLE_ENDIAN), ++ HPPA(32, ByteOrder.BIG_ENDIAN), ++ IA64(64, ByteOrder.LITTLE_ENDIAN), ++ M68K(32, ByteOrder.BIG_ENDIAN), ++ SH(32, ByteOrder.LITTLE_ENDIAN), ++ X32(32, ByteOrder.LITTLE_ENDIAN), + OTHER(is64bit() ? 64 : 32, ByteOrder.nativeOrder()), + PPC(32, ByteOrder.BIG_ENDIAN), + PPC64(64, ByteOrder.BIG_ENDIAN), +@@ -181,6 +188,69 @@ public enum Architecture { } /** @@ -103,63 +86,46 @@ @ForceInline --- a/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template +++ b/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template -@@ -60,4 +60,12 @@ class PlatformProps { - static final boolean TARGET_ARCH_IS_PPC64 = "@@OPENJDK_TARGET_CPU@@" == "ppc64"; - static final boolean TARGET_ARCH_IS_MIPSEL = "@@OPENJDK_TARGET_CPU@@" == "mipsel"; - static final boolean TARGET_ARCH_IS_MIPS64EL= "@@OPENJDK_TARGET_CPU@@" == "mips64el"; -+ static final boolean TARGET_ARCH_IS_X32 = "@@OPENJDK_TARGET_CPU@@" == "x32"; -+ static final boolean TARGET_ARCH_IS_SH = "@@OPENJDK_TARGET_CPU@@" == "sh"; -+ static final boolean TARGET_ARCH_IS_M68K = "@@OPENJDK_TARGET_CPU@@" == "m68k"; -+ static final boolean TARGET_ARCH_IS_PPC = "@@OPENJDK_TARGET_CPU@@" == "ppc"; +@@ -65,5 +65,12 @@ class PlatformProps { + static final boolean TARGET_ARCH_IS_SPARCV9 = "@@OPENJDK_TARGET_CPU@@" == "sparcv9"; + static final boolean TARGET_ARCH_IS_X86 = "@@OPENJDK_TARGET_CPU@@" == "x86"; + static final boolean TARGET_ARCH_IS_X64 = "@@OPENJDK_TARGET_CPU@@" == "x64"; + static final boolean TARGET_ARCH_IS_ALPHA = "@@OPENJDK_TARGET_CPU@@" == "alpha"; + static final boolean TARGET_ARCH_IS_ARC = "@@OPENJDK_TARGET_CPU@@" == "arc"; + static final boolean TARGET_ARCH_IS_HPPA = "@@OPENJDK_TARGET_CPU@@" == "hppa"; + static final boolean TARGET_ARCH_IS_IA64 = "@@OPENJDK_TARGET_CPU@@" == "ia64"; ++ static final boolean TARGET_ARCH_IS_M68K = "@@OPENJDK_TARGET_CPU@@" == "m68k"; ++ static final boolean TARGET_ARCH_IS_SH = "@@OPENJDK_TARGET_CPU@@" == "sh"; ++ static final boolean TARGET_ARCH_IS_X32 = "@@OPENJDK_TARGET_CPU@@" == "x32"; + } --- a/test/jdk/jdk/internal/util/ArchTest.java +++ b/test/jdk/jdk/internal/util/ArchTest.java -@@ -35,6 +35,14 @@ import static jdk.internal.util.Architec - import static jdk.internal.util.Architecture.S390; +@@ -41,6 +41,13 @@ import static jdk.internal.util.Architec + import static jdk.internal.util.Architecture.SPARCV9; import static jdk.internal.util.Architecture.X64; import static jdk.internal.util.Architecture.X86; +import static jdk.internal.util.Architecture.ALPHA; +import static jdk.internal.util.Architecture.ARC; +import static jdk.internal.util.Architecture.HPPA; +import static jdk.internal.util.Architecture.IA64; -+import static jdk.internal.util.Architecture.PPC; +import static jdk.internal.util.Architecture.SH; +import static jdk.internal.util.Architecture.X32; +import static jdk.internal.util.Architecture.M68K; - import static jdk.internal.util.Architecture.MIPSEL; - import static jdk.internal.util.Architecture.MIPS64EL; -@@ -78,6 +86,14 @@ public class ArchTest { - case "ppc64", "ppc64le" -> PPC64; - case "mipsel" -> MIPSEL; - case "mips64el" -> MIPS64EL; -+ case "alpha" -> ALPHA; -+ case "arc" -> ARC; -+ case "hppa" -> HPPA; -+ case "ia64" -> IA64; -+ case "m68k" -> M68K; -+ case "ppc" -> PPC; -+ case "sh" -> SH; -+ case "x32" -> X32; - default -> OTHER; - }; - assertEquals(Architecture.current(), arch, "mismatch in Architecture.current vs " + osArch); -@@ -98,6 +114,14 @@ public class ArchTest { - Arguments.of(S390, Architecture.isS390()), - Arguments.of(MIPSEL, Architecture.isMIPSEL()), - Arguments.of(MIPS64EL, Architecture.isMIPS64EL()), -+ Arguments.of(PPC, Architecture.isPPC()), -+ Arguments.of(M68K, Architecture.isM68K()), -+ Arguments.of(ALPHA, Architecture.isALPHA()), -+ Arguments.of(ARC, Architecture.isARC()), -+ Arguments.of(HPPA, Architecture.isHPPA()), -+ Arguments.of(IA64, Architecture.isIA64()), -+ Arguments.of(SH, Architecture.isSH()), -+ Arguments.of(X32, Architecture.isX32()), - Arguments.of(PPC64, Architecture.isPPC64()) + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; +@@ -92,6 +99,13 @@ public class ArchTest { + Arguments.of("x64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64()), + Arguments.of("x86", X86, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isX86()), + Arguments.of("x86_64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64()) ++ Arguments.of("alpha", ALPHA, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isALPHA()), ++ Arguments.of("arc", ARC, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isARC()), ++ Arguments.of("hppa", HPPA, 32, ByteOrder.BIG_ENDIAN, Architecture.isHPPA()), ++ Arguments.of("ia64", IA64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isIA64()), ++ Arguments.of("m68k", M68K, 32, ByteOrder.BIG_ENDIAN, Architecture.isM68K()), ++ Arguments.of("sh", SH, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isSH()), ++ Arguments.of("x32", X32, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isX32()), ); } + diff -Nru openjdk-21-21.0.1+12/debian/patches/mips.diff openjdk-21-21.0.2+13/debian/patches/mips.diff --- openjdk-21-21.0.1+12/debian/patches/mips.diff 2023-10-23 06:32:18.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/patches/mips.diff 2024-01-17 12:14:57.000000000 +0000 @@ -2,7 +2,7 @@ --- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c +++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c -@@ -156,7 +156,7 @@ +@@ -259,7 +259,7 @@ static statx_func* my_statx_func = NULL; /** * fstatat missing from glibc on Linux. */ diff -Nru openjdk-21-21.0.1+12/debian/patches/reproducible-build-jmod.diff openjdk-21-21.0.2+13/debian/patches/reproducible-build-jmod.diff --- openjdk-21-21.0.1+12/debian/patches/reproducible-build-jmod.diff 2023-10-23 06:32:18.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/patches/reproducible-build-jmod.diff 2024-01-17 12:14:57.000000000 +0000 @@ -12,7 +12,7 @@ --- a/make/CreateJmods.gmk +++ b/make/CreateJmods.gmk -@@ -242,6 +242,15 @@ +@@ -228,6 +228,15 @@ endif # Create jmods in the support dir and then move them into place to keep the # module path in $(IMAGES_OUTPUTDIR)/jmods valid at all times. @@ -28,7 +28,7 @@ $(eval $(call SetupExecute, create_$(JMOD_FILE), \ WARN := Creating $(INTERIM_MSG)$(JMOD_FILE), \ DEPS := $(DEPS), \ -@@ -253,7 +262,7 @@ +@@ -239,7 +248,7 @@ $(eval $(call SetupExecute, create_$(JMO --module-path $(JMODS_DIR) $(JMOD_FLAGS) \ --date $(SOURCE_DATE_ISO_8601) \ $(JMODS_SUPPORT_DIR)/$(JMOD_FILE), \ diff -Nru openjdk-21-21.0.1+12/debian/patches/system-pcsclite.diff openjdk-21-21.0.2+13/debian/patches/system-pcsclite.diff --- openjdk-21-21.0.1+12/debian/patches/system-pcsclite.diff 2023-10-23 06:32:18.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/patches/system-pcsclite.diff 2024-01-17 12:14:57.000000000 +0000 @@ -1,6 +1,6 @@ --- a/make/autoconf/lib-bundled.m4 +++ b/make/autoconf/lib-bundled.m4 -@@ -41,6 +41,7 @@ +@@ -41,6 +41,7 @@ AC_DEFUN_ONCE([LIB_SETUP_BUNDLED_LIBS], LIB_SETUP_ZLIB LIB_SETUP_LCMS LIB_SETUP_HARFBUZZ @@ -8,7 +8,7 @@ ]) ################################################################################ -@@ -309,3 +310,41 @@ +@@ -309,3 +310,41 @@ AC_DEFUN_ONCE([LIB_SETUP_HARFBUZZ], AC_SUBST(HARFBUZZ_CFLAGS) AC_SUBST(HARFBUZZ_LIBS) ]) @@ -52,7 +52,7 @@ +]) --- a/make/modules/java.smartcardio/Lib.gmk +++ b/make/modules/java.smartcardio/Lib.gmk -@@ -30,12 +30,12 @@ +@@ -30,12 +30,12 @@ include LibCommon.gmk $(eval $(call SetupJdkLibrary, BUILD_LIBJ2PCSC, \ NAME := j2pcsc, \ CFLAGS := $(CFLAGS_JDKLIB), \ @@ -70,7 +70,7 @@ --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in -@@ -800,6 +800,7 @@ +@@ -805,6 +805,7 @@ TAR_SUPPORTS_TRANSFORM:=@TAR_SUPPORTS_TR # Build setup USE_EXTERNAL_LIBJPEG:=@USE_EXTERNAL_LIBJPEG@ USE_EXTERNAL_LIBGIF:=@USE_EXTERNAL_LIBGIF@ @@ -88,7 +88,7 @@ void *hModule; FPTR_SCardEstablishContext scardEstablishContext; FPTR_SCardConnect scardConnect; -@@ -47,6 +48,7 @@ +@@ -47,6 +48,7 @@ FPTR_SCardListReaders scardListReaders; FPTR_SCardBeginTransaction scardBeginTransaction; FPTR_SCardEndTransaction scardEndTransaction; FPTR_SCardControl scardControl; @@ -96,7 +96,7 @@ /* * Throws a Java Exception by name -@@ -74,8 +76,9 @@ +@@ -74,8 +76,9 @@ static void throwIOException(JNIEnv *env { throwByName(env, "java/io/IOException", msg); } @@ -107,7 +107,7 @@ void *fAddress = dlsym(hModule, functionName); if (fAddress == NULL) { char errorMessage[256]; -@@ -85,9 +88,11 @@ +@@ -85,9 +88,11 @@ static void *findFunction(JNIEnv *env, v } return fAddress; } @@ -119,7 +119,7 @@ const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL); if (libName == NULL) { throwNullPointerException(env, "PCSC library name is null"); -@@ -141,4 +146,5 @@ +@@ -141,4 +146,5 @@ JNIEXPORT void JNICALL Java_sun_security #else scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl132"); #endif // __APPLE__ @@ -136,7 +136,7 @@ typedef LONG (*FPTR_SCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, -@@ -111,3 +113,41 @@ +@@ -111,3 +113,41 @@ extern FPTR_SCardListReaders scardListRe extern FPTR_SCardBeginTransaction scardBeginTransaction; extern FPTR_SCardEndTransaction scardEndTransaction; extern FPTR_SCardControl scardControl; @@ -180,7 +180,7 @@ +#endif --- a/test/jdk/java/security/misc/Versions.java +++ b/test/jdk/java/security/misc/Versions.java -@@ -55,12 +55,7 @@ +@@ -55,12 +55,7 @@ public class Versions { Pattern.compile("list/(?[0-9a-f]+)/public_suffix_list.dat"), "src/java.base/share/legal/public_suffix.md", Pattern.compile("list/(?[0-9a-f]+)/public_suffix_list.dat"), diff -Nru openjdk-21-21.0.1+12/debian/rules openjdk-21-21.0.2+13/debian/rules --- openjdk-21-21.0.1+12/debian/rules 2023-11-23 19:36:12.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/rules 2024-01-17 12:14:57.000000000 +0000 @@ -871,7 +871,7 @@ control_vars += '-Vdbg:Conflicts=openjdk-11-dbg, openjdk-12-dbg, openjdk-13-dbg, openjdk-14-dbg, openjdk-15-dbg, openjdk-16-dbg' endif -debian/control: debian/control.in debian/tests/control debian/rules +debian/control: debian/control.in debian/tests/control debian/rules debian/watch @cp -p debian/control debian/control.old sed \ -e 's/@basename@/$(basename)/g' \ @@ -899,6 +899,7 @@ $(if $(altzero_archs), debian/control.zero-jre) \ $(if $(DEB_HOST_MULTIARCH),,| grep -v '^Multi-Arch') \ > debian/control + sed -i 's/[[:blank:]]*$$//' debian/control @if cmp -s debian/control debian/control.old; then \ rm -f debian/control.old; \ else \ @@ -1885,25 +1886,35 @@ NO_PKG_MANGLE=1 \ dh_builddeb -a $(nodemo) $(nojrez) #$(bd_options) -is_release = yes -#is_release = git_project = jdk21u -git_tag = jdk-21.0.1+12 +git_tag = jdk-21.0.2+13 package_version = $(shell echo $(PKGVERSION) | sed 's/-[^-][^-]*$$//') -ifneq ($(is_release),yes) +ifneq ($(is_upstream_release),yes) package_version := $(subst +,~,$(package_version)) endif git_url = https://github.com/openjdk/$(git_project) origdir = ../$(basename)-$(package_version).orig topdir = $(basename)-$(package_version) -gtest_repo = https://github.com/google/googletest/archive/refs/tags/ +gtest_repo = https://github.com/google/googletest gtest_tag = 1.14.0 gtestdir = ../$(basename)-$(package_version)-googletest.orig +debian/watch: debian/watch.in debian/rules + sed \ + -e 's|@git_url@|$(git_url)/tags|g' \ + -e 's|@gtest_repo@|$(gtest_repo)/tags|g' \ + -e 's|@gtest_tag@|$(gtest_tag)|g' \ + -e 's|@shortver@|$(shortver)|g' \ + debian/watch.in > debian/watch +# disable version mangling for the release version +ifeq ($(is_upstream_release),yes) + sed -i 's|repack.*\\|repack,\\|g' debian/watch +endif + get-gtest: rm -rf $(gtestdir) || true mkdir $(gtestdir) - wget -O $(gtestdir)/googletest.tar.gz $(gtest_repo)/v$(gtest_tag).tar.gz + wget -O $(gtestdir)/googletest.tar.gz $(gtest_repo)/archive/refs/tags/v$(gtest_tag).tar.gz set -ex; \ repo=googletest; \ d=$$(tar tf $(gtestdir)/$$repo.tar.gz | head -1 | sed 's,/.*,,'); \ diff -Nru openjdk-21-21.0.1+12/debian/tests/control openjdk-21-21.0.2+13/debian/tests/control --- openjdk-21-21.0.1+12/debian/tests/control 2023-11-23 19:36:13.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/tests/control 2024-01-17 12:14:57.000000000 +0000 @@ -7,9 +7,9 @@ Restrictions: superficial #Tests: hotspot, jaxp, langtools -#Depends: @, jtreg7:native (>= 7.2+1~), libtestng7-java:native, build-essential +#Depends: @, jtreg7:native (>= 7.3.1+1~), libtestng7-java:native, build-essential #Restrictions: allow-stderr, skippable, flaky #Tests: jdk -#Depends: @, jtreg7:native (>= 7.2+1~), libtestng7-java:native, build-essential, xfwm4:native, xvfb, dbus-x11 +#Depends: @, jtreg7:native (>= 7.3.1+1~), libtestng7-java:native, build-essential, xfwm4:native, xvfb, dbus-x11 #Restrictions: allow-stderr, skippable, flaky diff -Nru openjdk-21-21.0.1+12/debian/watch openjdk-21-21.0.2+13/debian/watch --- openjdk-21-21.0.1+12/debian/watch 2023-10-23 06:32:18.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/watch 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -version=4 -opts=\ -repack,\ -compression=xz,\ -dversionmangle=s/~\d*\~us\d*$/\+\d*/, \ - https://github.com/openjdk/jdk21u/tags \ - (?:.*?/)?jdk-(21[\.\d]*)\.tar\.gz - -opts=\ -component=googletest,\ -repack,\ -compression=xz \ - https://github.com/google/googletest/tags \ - (?:.*?/)?v(1.14.0)\.tar\.gz diff -Nru openjdk-21-21.0.1+12/debian/watch.in openjdk-21-21.0.2+13/debian/watch.in --- openjdk-21-21.0.1+12/debian/watch.in 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/debian/watch.in 2024-01-17 12:14:57.000000000 +0000 @@ -0,0 +1,13 @@ +version=4 +opts=\ +repack,repacksuffix=ea,oversionmangle=s/\+(\d+)/\~$1/,dversionmangle=s/\~(\d*)ea$/\+$1/,\ +compression=xz, \ + @git_url@ \ + (?:.*?/)?jdk-(@shortver@[\+\.\d]*)\.tar\.gz + +opts=\ +component=googletest,\ +repack,\ +compression=xz \ + @gtest_repo@ \ + (?:.*?/)?v([\.\d]+)\.tar\.gz @gtest_tag@ diff -Nru openjdk-21-21.0.1+12/make/CreateJmods.gmk openjdk-21-21.0.2+13/make/CreateJmods.gmk --- openjdk-21-21.0.1+12/make/CreateJmods.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/CreateJmods.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -81,13 +81,11 @@ ifneq ($(CMDS_DIR), ) DEPS += $(call FindFiles, $(CMDS_DIR)) ifeq ($(call isTargetOs, windows)+$(SHIP_DEBUG_SYMBOLS), true+public) - # For public debug symbols on Windows, we have to use stripped pdbs, rename them - # and filter out a few launcher pdbs where there's a lib that goes by the same name + # For public debug symbols on Windows, we have to use stripped pdbs and rename them rename_stripped = $(patsubst %.stripped.pdb,%.pdb,$1) CMDS_DIR_FILTERED := $(subst modules_cmds,modules_cmds_filtered, $(CMDS_DIR)) FILES_CMDS := $(filter-out %.pdb, $(call FindFiles, $(CMDS_DIR))) \ - $(filter-out %jimage.stripped.pdb %jpackage.stripped.pdb %java.stripped.pdb, \ - $(filter %.stripped.pdb, $(call FindFiles, $(CMDS_DIR)))) + $(filter %.stripped.pdb, $(call FindFiles, $(CMDS_DIR))) $(eval $(call SetupCopyFiles, COPY_FILTERED_CMDS, \ SRC := $(CMDS_DIR), \ DEST := $(CMDS_DIR_FILTERED), \ @@ -96,18 +94,6 @@ )) DEPS += $(COPY_FILTERED_CMDS) JMOD_FLAGS += --cmds $(CMDS_DIR_FILTERED) - else ifeq ($(call isTargetOs, windows)+$(SHIP_DEBUG_SYMBOLS), true+full) - # For full debug symbols on Windows, we have to filter out a few launcher pdbs - # where there's a lib that goes by the same name - CMDS_DIR_FILTERED := $(subst modules_cmds,modules_cmds_filtered, $(CMDS_DIR)) - $(eval $(call SetupCopyFiles, COPY_FILTERED_CMDS, \ - SRC := $(CMDS_DIR), \ - DEST := $(CMDS_DIR_FILTERED), \ - FILES := $(filter-out %jimage.pdb %jpackage.pdb %java.pdb, \ - $(call FindFiles, $(CMDS_DIR))), \ - )) - DEPS += $(COPY_FILTERED_CMDS) - JMOD_FLAGS += --cmds $(CMDS_DIR_FILTERED) else JMOD_FLAGS += --cmds $(CMDS_DIR) endif diff -Nru openjdk-21-21.0.1+12/make/Images.gmk openjdk-21-21.0.2+13/make/Images.gmk --- openjdk-21-21.0.1+12/make/Images.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/Images.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -267,9 +267,6 @@ endif endif -FILTERED_PDBS := %jimage.stripped.pdb %jpackage.stripped.pdb %java.stripped.pdb \ - %jimage.pdb %jpackage.pdb %java.pdb %jimage.map %jpackage.map %java.map - # Param 1 - either JDK or JRE SetupCopyDebuginfo = \ $(foreach m, $(ALL_$1_MODULES), \ @@ -283,8 +280,8 @@ $(eval $(call SetupCopyFiles, COPY_$1_CMDS_DEBUGINFO_$m, \ SRC := $(SUPPORT_OUTPUTDIR)/modules_cmds/$m, \ DEST := $($1_IMAGE_DIR)/$(CMDS_TARGET_SUBDIR), \ - FILES := $(filter-out $(FILTERED_PDBS), $(call FindDebuginfoFiles, \ - $(SUPPORT_OUTPUTDIR)/modules_cmds/$m)), \ + FILES := $(call FindDebuginfoFiles, \ + $(SUPPORT_OUTPUTDIR)/modules_cmds/$m), \ )) \ $(eval $1_TARGETS += $$(COPY_$1_CMDS_DEBUGINFO_$m)) \ ) diff -Nru openjdk-21-21.0.1+12/make/JrtfsJar.gmk openjdk-21-21.0.2+13/make/JrtfsJar.gmk --- openjdk-21-21.0.1+12/make/JrtfsJar.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/JrtfsJar.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -46,8 +46,10 @@ jdk/internal/jrtfs \ # +# Compile jrt-fs.jar with the interim compiler, as it +# ends up in the image, this will ensure reproducible classes $(eval $(call SetupJavaCompilation, BUILD_JRTFS, \ - COMPILER := bootjdk, \ + COMPILER := interim, \ DISABLED_WARNINGS := options, \ TARGET_RELEASE := $(TARGET_RELEASE_JDK8), \ SRC := $(TOPDIR)/src/java.base/share/classes, \ diff -Nru openjdk-21-21.0.1+12/make/RunTests.gmk openjdk-21-21.0.2+13/make/RunTests.gmk --- openjdk-21-21.0.1+12/make/RunTests.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/RunTests.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -178,7 +178,8 @@ c = c * $(TEST_JOBS_FACTOR_JDL); \ c = c * $(TEST_JOBS_FACTOR_MACHINE); \ if (c < 1) c = 1; \ - printf "%.0f", c; \ + c = c + 0.5; \ + printf "%d", c; \ }') endif @@ -356,7 +357,7 @@ # with test id: dir/Test.java#selection -> Test.java#selection -> .java#selection -> #selection # without: dir/Test.java -> Test.java -> .java -> <> TestID = \ - $(subst .sh,,$(subst .html,,$(subst .java,,$(suffix $(notdir $1))))) + $(subst .jasm,,$(subst .sh,,$(subst .html,,$(subst .java,,$(suffix $(notdir $1)))))) # The test id starting with a hash (#testid) will be stripped by all # evals in ParseJtregTestSelectionInner and will be reinserted by calling @@ -860,11 +861,12 @@ $$(eval $$(call SetupRunJtregTestCustom, $1)) - clean-workdir-$1: + clean-outputdirs-$1: $$(RM) -r $$($1_TEST_SUPPORT_DIR) + $$(RM) -r $$($1_TEST_RESULTS_DIR) $1_COMMAND_LINE := \ - $$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \ + $$(JTREG_JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \ -Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \ $$($1_JTREG_BASIC_OPTIONS) \ -testjdk:$$(JDK_UNDER_TEST) \ @@ -907,7 +909,7 @@ done endif - run-test-$1: pre-run-test clean-workdir-$1 + run-test-$1: pre-run-test clean-outputdirs-$1 $$(call LogWarn) $$(call LogWarn, Running test '$$($1_TEST)') $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR) \ @@ -944,9 +946,9 @@ $$(eval $1_TOTAL := 1) \ ) - $1: run-test-$1 parse-test-$1 clean-workdir-$1 + $1: run-test-$1 parse-test-$1 clean-outputdirs-$1 - TARGETS += $1 run-test-$1 parse-test-$1 clean-workdir-$1 + TARGETS += $1 run-test-$1 parse-test-$1 clean-outputdirs-$1 TEST_TARGETS += parse-test-$1 endef diff -Nru openjdk-21-21.0.1+12/make/RunTestsPrebuilt.gmk openjdk-21-21.0.2+13/make/RunTestsPrebuilt.gmk --- openjdk-21-21.0.1+12/make/RunTestsPrebuilt.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/RunTestsPrebuilt.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -122,6 +122,7 @@ $(eval $(call SetupVariable,JDK_IMAGE_DIR,$(OUTPUTDIR)/images/jdk)) $(eval $(call SetupVariable,TEST_IMAGE_DIR,$(OUTPUTDIR)/images/test)) $(eval $(call SetupVariable,SYMBOLS_IMAGE_DIR,$(OUTPUTDIR)/images/symbols,NO_CHECK)) +$(eval $(call SetupVariable,JTREG_JDK,$(BOOT_JDK))) # Provide default values for tools that we need $(eval $(call SetupVariable,MAKE,make,NO_CHECK)) @@ -157,6 +158,10 @@ OPENJDK_TARGET_OS := windows OPENJDK_TARGET_OS_TYPE := windows OPENJDK_TARGET_OS_ENV := windows.cygwin +else ifeq ($(UNAME_OS), MINGW64) + OPENJDK_TARGET_OS := windows + OPENJDK_TARGET_OS_TYPE := windows + OPENJDK_TARGET_OS_ENV := windows.msys2 else OPENJDK_TARGET_OS_TYPE:=unix ifeq ($(UNAME_OS), Linux) @@ -169,6 +174,9 @@ OPENJDK_TARGET_OS_ENV := $(OPENJDK_TARGET_OS) endif +# Sanity check env detection +$(info Detected target OS, type and env: [$(OPENJDK_TARGET_OS)] [$(OPENJDK_TARGET_OS_TYPE)] [$(OPENJDK_TARGET_OS_ENV)]) + # Assume little endian unless otherwise specified OPENJDK_TARGET_CPU_ENDIAN := little @@ -248,6 +256,7 @@ TOPDIR := $(TOPDIR), \ OUTPUTDIR := $(OUTPUTDIR), \ BOOT_JDK := $(BOOT_JDK), \ + JTREG_JDK := $(JTREG_JDK), \ JT_HOME := $(JT_HOME), \ JDK_IMAGE_DIR := $(JDK_IMAGE_DIR), \ JCOV_IMAGE_DIR := $(JCOV_IMAGE_DIR), \ diff -Nru openjdk-21-21.0.1+12/make/RunTestsPrebuiltSpec.gmk openjdk-21-21.0.2+13/make/RunTestsPrebuiltSpec.gmk --- openjdk-21-21.0.1+12/make/RunTestsPrebuiltSpec.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/RunTestsPrebuiltSpec.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -124,6 +124,8 @@ JLINK := $(FIXPATH) $(JLINK_CMD) JMOD := $(FIXPATH) $(JMOD_CMD) +JTREG_JAVA := $(FIXPATH) $(JTREG_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS) + BUILD_JAVA := $(JDK_IMAGE_DIR)/bin/JAVA ################################################################################ # Some common tools. Assume most common name and no path. diff -Nru openjdk-21-21.0.1+12/make/ZipSecurity.gmk openjdk-21-21.0.2+13/make/ZipSecurity.gmk --- openjdk-21-21.0.1+12/make/ZipSecurity.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/ZipSecurity.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -88,9 +88,9 @@ $(eval $(call SetupZipArchive,BUILD_JGSS_BIN_ZIP, \ SRC := $(SUPPORT_OUTPUTDIR), \ INCLUDE_FILES := modules_libs/java.security.jgss/w2k_lsa_auth.dll \ - modules_libs/java.security.jgss/w2k_lsa_auth.diz \ - modules_libs/java.security.jgss/w2k_lsa_auth.map \ - modules_libs/java.security.jgss/w2k_lsa_auth.pdb, \ + modules_libs/java.security.jgss/w2k_lsa_auth.dll.diz \ + modules_libs/java.security.jgss/w2k_lsa_auth.dll.map \ + modules_libs/java.security.jgss/w2k_lsa_auth.dll.pdb, \ ZIP := $(IMAGES_OUTPUTDIR)/$(JGSS_ZIP_NAME))) TARGETS += $(IMAGES_OUTPUTDIR)/$(JGSS_ZIP_NAME) diff -Nru openjdk-21-21.0.1+12/make/autoconf/basic.m4 openjdk-21-21.0.2+13/make/autoconf/basic.m4 --- openjdk-21-21.0.1+12/make/autoconf/basic.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/basic.m4 2024-01-16 16:19:00.000000000 +0000 @@ -406,9 +406,9 @@ # WARNING: This might be a bad thing to do. You need to be sure you want to # have a configuration in this directory. Do some sanity checks! - if test ! -e "$OUTPUTDIR/spec.gmk"; then - # If we have a spec.gmk, we have run here before and we are OK. Otherwise, check for - # other files + if test ! -e "$OUTPUTDIR/spec.gmk" && test ! -e "$OUTPUTDIR/configure-support/generated-configure.sh"; then + # If we have a spec.gmk or configure-support/generated-configure.sh, + # we have run here before and we are OK. Otherwise, check for other files files_present=`$LS $OUTPUTDIR` # Configure has already touched config.log and confdefs.h in the current dir when this check # is performed. @@ -423,8 +423,9 @@ AC_MSG_NOTICE([Current directory is $CONFIGURE_START_DIR.]) AC_MSG_NOTICE([Since this is not the source root, configure will output the configuration here]) AC_MSG_NOTICE([(as opposed to creating a configuration in /build/).]) - AC_MSG_NOTICE([However, this directory is not empty. This is not allowed, since it could]) - AC_MSG_NOTICE([seriously mess up just about everything.]) + AC_MSG_NOTICE([However, this directory is not empty, additionally to some allowed files]) + AC_MSG_NOTICE([it contains $filtered_files.]) + AC_MSG_NOTICE([This is not allowed, since it could seriously mess up just about everything.]) AC_MSG_NOTICE([Try 'cd $TOPDIR' and restart configure]) AC_MSG_NOTICE([(or create a new empty directory and cd to it).]) AC_MSG_ERROR([Will not continue creating configuration in $CONFIGURE_START_DIR]) diff -Nru openjdk-21-21.0.1+12/make/autoconf/flags-cflags.m4 openjdk-21-21.0.2+13/make/autoconf/flags-cflags.m4 --- openjdk-21-21.0.1+12/make/autoconf/flags-cflags.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/flags-cflags.m4 2024-01-16 16:19:00.000000000 +0000 @@ -816,6 +816,7 @@ REPRODUCIBLE_CFLAGS= ] ) + AC_SUBST(REPRODUCIBLE_CFLAGS) fi # Prevent the __FILE__ macro from generating absolute paths into the built @@ -849,6 +850,22 @@ FILE_MACRO_CFLAGS= ] ) + if test "x$FILE_MACRO_CFLAGS" != x; then + # Add -pathmap for all VS system include paths using Windows + # full Long path name that is generated by the compiler + # Not enabled under WSL as there is no easy way to obtain the + # Windows full long paths, thus reproducible WSL builds will + # depend on building with the same VS toolchain install location. + if test "x$OPENJDK_BUILD_OS_ENV" != "xwindows.wsl1" && test "x$OPENJDK_BUILD_OS_ENV" != "xwindows.wsl2"; then + for ipath in ${$3SYSROOT_CFLAGS}; do + if test "x${ipath:0:2}" == "x-I"; then + ipath_path=${ipath#"-I"} + UTIL_FIXUP_WIN_LONG_PATH(ipath_path) + FILE_MACRO_CFLAGS="$FILE_MACRO_CFLAGS -pathmap:\"$ipath_path\"=vsi" + fi + done + fi + fi fi AC_MSG_CHECKING([how to prevent absolute paths in output]) diff -Nru openjdk-21-21.0.1+12/make/autoconf/flags-other.m4 openjdk-21-21.0.2+13/make/autoconf/flags-other.m4 --- openjdk-21-21.0.1+12/make/autoconf/flags-other.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/flags-other.m4 2024-01-16 16:19:00.000000000 +0000 @@ -88,6 +88,16 @@ AC_SUBST(RCFLAGS) ]) +AC_DEFUN([FLAGS_SETUP_NMFLAGS], +[ + # On AIX, we need to set NM flag -X64 for processing 64bit object files + if test "x$OPENJDK_TARGET_OS" = xaix; then + NMFLAGS="-X64" + fi + + AC_SUBST(NMFLAGS) +]) + ################################################################################ # platform independent AC_DEFUN([FLAGS_SETUP_ASFLAGS], diff -Nru openjdk-21-21.0.1+12/make/autoconf/flags.m4 openjdk-21-21.0.2+13/make/autoconf/flags.m4 --- openjdk-21-21.0.1+12/make/autoconf/flags.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/flags.m4 2024-01-16 16:19:00.000000000 +0000 @@ -428,6 +428,7 @@ FLAGS_SETUP_ARFLAGS FLAGS_SETUP_STRIPFLAGS FLAGS_SETUP_RCFLAGS + FLAGS_SETUP_NMFLAGS FLAGS_SETUP_ASFLAGS FLAGS_SETUP_ASFLAGS_CPU_DEP([TARGET]) diff -Nru openjdk-21-21.0.1+12/make/autoconf/lib-cups.m4 openjdk-21-21.0.2+13/make/autoconf/lib-cups.m4 --- openjdk-21-21.0.1+12/make/autoconf/lib-cups.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/lib-cups.m4 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2016, 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 @@ -68,12 +68,20 @@ fi fi if test "x$CUPS_FOUND" = xno; then - # Are the cups headers installed in the default /usr/include location? - AC_CHECK_HEADERS([cups/cups.h cups/ppd.h], [ - CUPS_FOUND=yes - CUPS_CFLAGS= - DEFAULT_CUPS=yes - ]) + # Are the cups headers installed in the default AIX or /usr/include location? + if test "x$OPENJDK_TARGET_OS" = "xaix"; then + AC_CHECK_HEADERS([/opt/freeware/include/cups/cups.h /opt/freeware/include/cups/ppd.h], [ + CUPS_FOUND=yes + CUPS_CFLAGS="-I/opt/freeware/include" + DEFAULT_CUPS=yes + ]) + else + AC_CHECK_HEADERS([cups/cups.h cups/ppd.h], [ + CUPS_FOUND=yes + CUPS_CFLAGS= + DEFAULT_CUPS=yes + ]) + fi fi if test "x$CUPS_FOUND" = xno; then HELP_MSG_MISSING_DEPENDENCY([cups]) diff -Nru openjdk-21-21.0.1+12/make/autoconf/lib-tests.m4 openjdk-21-21.0.2+13/make/autoconf/lib-tests.m4 --- openjdk-21-21.0.1+12/make/autoconf/lib-tests.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/lib-tests.m4 2024-01-16 16:19:00.000000000 +0000 @@ -28,7 +28,7 @@ ################################################################################ # Minimum supported versions -JTREG_MINIMUM_VERSION=7.2 +JTREG_MINIMUM_VERSION=7.3.1 GTEST_MINIMUM_VERSION=1.13.0 ############################################################################### @@ -227,12 +227,47 @@ UTIL_FIXUP_PATH(JT_HOME) AC_SUBST(JT_HOME) + # Specify a JDK for running jtreg. Defaults to the BOOT_JDK. + AC_ARG_WITH(jtreg-jdk, [AS_HELP_STRING([--with-jdk], + [path to JDK for running jtreg @<:@BOOT_JDK@:>@])]) + + AC_MSG_CHECKING([for jtreg jdk]) + if test "x${with_jtreg_jdk}" != x; then + if test "x${with_jtreg_jdk}" = xno; then + AC_MSG_RESULT([no, jtreg jdk not specified]) + elif test "x${with_jtreg_jdk}" = xyes; then + AC_MSG_RESULT([not specified]) + AC_MSG_ERROR([--with-jtreg-jdk needs a value]) + else + JTREG_JDK="${with_jtreg_jdk}" + AC_MSG_RESULT([$JTREG_JDK]) + UTIL_FIXUP_PATH(JTREG_JDK) + if test ! -f "$JTREG_JDK/bin/java"; then + AC_MSG_ERROR([Could not find jtreg java at $JTREG_JDK/bin/java]) + fi + fi + else + JTREG_JDK="${BOOT_JDK}" + AC_MSG_RESULT([no, using BOOT_JDK]) + fi + + UTIL_FIXUP_PATH(JTREG_JDK) + AC_SUBST([JTREG_JDK]) + # For use in the configure script + JTREG_JAVA="$FIXPATH $JTREG_JDK/bin/java" + # Verify jtreg version if test "x$JT_HOME" != x; then + AC_MSG_CHECKING([jtreg jar existence]) + if test ! -f "$JT_HOME/lib/jtreg.jar"; then + AC_MSG_ERROR([Could not find jtreg jar at $JT_HOME/lib/jtreg.jar]) + fi + AC_MSG_CHECKING([jtreg version number]) # jtreg -version looks like this: "jtreg 6.1+1-19" # Extract actual version part ("6.1" in this case) - jtreg_version_full=`$JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2` + jtreg_version_full=$($JTREG_JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2) + jtreg_version=${jtreg_version_full/%+*} AC_MSG_RESULT([$jtreg_version]) diff -Nru openjdk-21-21.0.1+12/make/autoconf/lib-x11.m4 openjdk-21-21.0.2+13/make/autoconf/lib-x11.m4 --- openjdk-21-21.0.1+12/make/autoconf/lib-x11.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/lib-x11.m4 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -35,6 +35,7 @@ X_CFLAGS= X_LIBS= else + x_libraries_orig="$x_libraries" if test "x${with_x}" = xno; then AC_MSG_ERROR([It is not possible to disable the use of X11. Remove the --without-x option.]) @@ -48,6 +49,7 @@ fi if test "x$x_libraries" = xNONE; then x_libraries="${with_x}/lib" + x_libraries_orig="$x_libraries" fi else # Check if the user has specified sysroot, but not --with-x, --x-includes or --x-libraries. @@ -82,8 +84,8 @@ AC_PATH_XTRA # AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling - # this doesn't make sense so we remove it. - if test "x$COMPILE_TYPE" = xcross; then + # this doesn't make sense so we remove it; same for sysroot (devkit). + if test "x$COMPILE_TYPE" = xcross || (test "x$SYSROOT" != "x" && test "x$x_libraries_orig" = xNONE); then X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[[^ ]]*//g'` fi diff -Nru openjdk-21-21.0.1+12/make/autoconf/libraries.m4 openjdk-21-21.0.2+13/make/autoconf/libraries.m4 --- openjdk-21-21.0.1+12/make/autoconf/libraries.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/libraries.m4 2024-01-16 16:19:00.000000000 +0000 @@ -108,12 +108,6 @@ BASIC_JVM_LIBS_$1="$BASIC_JVM_LIBS_$1 -latomic" fi fi - - # Because RISC-V only has word-sized atomics, it requires libatomic where - # other common architectures do not, so link libatomic by default. - if test "x$OPENJDK_$1_OS" = xlinux && test "x$OPENJDK_$1_CPU" = xriscv64; then - BASIC_JVM_LIBS_$1="$BASIC_JVM_LIBS_$1 -latomic" - fi ]) ################################################################################ diff -Nru openjdk-21-21.0.1+12/make/autoconf/spec.gmk.in openjdk-21-21.0.2+13/make/autoconf/spec.gmk.in --- openjdk-21-21.0.1+12/make/autoconf/spec.gmk.in 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/spec.gmk.in 2024-01-16 16:19:00.000000000 +0000 @@ -424,6 +424,7 @@ ENABLE_LIBFFI_BUNDLING:=@ENABLE_LIBFFI_BUNDLING@ LIBFFI_LIB_FILE:=@LIBFFI_LIB_FILE@ FILE_MACRO_CFLAGS := @FILE_MACRO_CFLAGS@ +REPRODUCIBLE_CFLAGS := @REPRODUCIBLE_CFLAGS@ BRANCH_PROTECTION_CFLAGS := @BRANCH_PROTECTION_CFLAGS@ STATIC_LIBS_CFLAGS := @STATIC_LIBS_CFLAGS@ @@ -601,6 +602,7 @@ ARFLAGS:=@ARFLAGS@ NM:=@NM@ +NMFLAGS:=@NMFLAGS@ STRIP:=@STRIP@ OBJDUMP:=@OBJDUMP@ CXXFILT:=@CXXFILT@ @@ -678,6 +680,9 @@ JLINK = $(JLINK_CMD) JMOD = $(JMOD_CMD) +JTREG_JDK := @JTREG_JDK@ +JTREG_JAVA = @FIXPATH@ $(JTREG_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS) + BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@ BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS) BUILD_JAVAC=@FIXPATH@ $(BUILD_JDK)/bin/javac diff -Nru openjdk-21-21.0.1+12/make/autoconf/util_paths.m4 openjdk-21-21.0.2+13/make/autoconf/util_paths.m4 --- openjdk-21-21.0.1+12/make/autoconf/util_paths.m4 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/autoconf/util_paths.m4 2024-01-16 16:19:00.000000000 +0000 @@ -118,6 +118,24 @@ fi ]) +############################################################################## +# Fixup path to be a Windows full long path +# Note: Only supported with cygwin/msys2 (cygpath tool) +AC_DEFUN([UTIL_FIXUP_WIN_LONG_PATH], +[ + # Only process if variable expands to non-empty + path="[$]$1" + if test "x$path" != x; then + if test "x$OPENJDK_BUILD_OS" = "xwindows"; then + win_path=$($PATHTOOL -wl "$path") + if test "x$win_path" != "x$path"; then + $1="$win_path" + fi + fi + fi +]) + + ############################################################################### # Check if the given file is a unix-style or windows-style executable, that is, # if it expects paths in unix-style or windows-style. diff -Nru openjdk-21-21.0.1+12/make/common/NativeCompilation.gmk openjdk-21-21.0.2+13/make/common/NativeCompilation.gmk --- openjdk-21-21.0.1+12/make/common/NativeCompilation.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/common/NativeCompilation.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -48,12 +48,12 @@ $(SED) -e 's/#.*//;s/global://;s/local://;s/\;//;s/^[ ]*/_/;/^_$$$$/d' | \ $(EGREP) -v "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" > \ $$(@D)/$$(basename $$(@F)).symbols || true; \ - $(NM) $$($1_TARGET) | $(GREP) " T " | \ + $(NM) $(NMFLAGS) $$($1_TARGET) | $(GREP) " T " | \ $(EGREP) "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" | \ $(CUT) -d ' ' -f 3 >> $$(@D)/$$(basename $$(@F)).symbols || true;\ else \ $(ECHO) "Getting symbols from nm"; \ - $(NM) -m $$($1_TARGET) | $(GREP) "__TEXT" | \ + $(NM) $(NMFLAGS) -m $$($1_TARGET) | $(GREP) "__TEXT" | \ $(EGREP) -v "non-external|private extern|__TEXT,__eh_frame" | \ $(SED) -e 's/.* //' > $$(@D)/$$(basename $$(@F)).symbols; \ fi @@ -1050,13 +1050,13 @@ ifneq ($$($1_TYPE), STATIC_LIBRARY) # Generate debuginfo files. ifeq ($(call isTargetOs, windows), true) - $1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb" \ - "-map:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map" + $1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_SYMBOLS_DIR)/$$($1_BASENAME).pdb" \ + "-map:$$($1_SYMBOLS_DIR)/$$($1_BASENAME).map" ifeq ($(SHIP_DEBUG_SYMBOLS), public) - $1_EXTRA_LDFLAGS += "-pdbstripped:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).stripped.pdb" + $1_EXTRA_LDFLAGS += "-pdbstripped:$$($1_SYMBOLS_DIR)/$$($1_BASENAME).stripped.pdb" endif - $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb \ - $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map + $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_BASENAME).pdb \ + $$($1_SYMBOLS_DIR)/$$($1_BASENAME).map else ifeq ($(call isTargetOs, linux), true) $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).debuginfo @@ -1104,7 +1104,11 @@ $1 += $$($1_DEBUGINFO_FILES) ifeq ($$($1_ZIP_EXTERNAL_DEBUG_SYMBOLS), true) - $1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).diz + ifeq ($(call isTargetOs, windows), true) + $1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_BASENAME).diz + else + $1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).diz + endif $1 += $$($1_DEBUGINFO_ZIP) # The dependency on TARGET is needed for debuginfo files diff -Nru openjdk-21-21.0.1+12/make/conf/github-actions.conf openjdk-21-21.0.2+13/make/conf/github-actions.conf --- openjdk-21-21.0.1+12/make/conf/github-actions.conf 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/conf/github-actions.conf 2024-01-16 16:19:00.000000000 +0000 @@ -26,7 +26,7 @@ # Versions and download locations for dependencies used by GitHub Actions (GHA) GTEST_VERSION=1.13.0 -JTREG_VERSION=7.2+1 +JTREG_VERSION=7.3.1+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 -Nru openjdk-21-21.0.1+12/make/conf/jib-profiles.js openjdk-21-21.0.2+13/make/conf/jib-profiles.js --- openjdk-21-21.0.1+12/make/conf/jib-profiles.js 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/conf/jib-profiles.js 2024-01-16 16:19:00.000000000 +0000 @@ -945,10 +945,7 @@ target_os: input.build_os, target_cpu: input.build_cpu, dependencies: [ "jtreg", "gnumake", "boot_jdk", "devkit", "jib" ], - labels: "test", - environment: { - "JT_JAVA": common.boot_jdk_home - } + labels: "test" } }; profiles = concatObjects(profiles, testOnlyProfiles); @@ -1188,9 +1185,9 @@ jtreg: { server: "jpg", product: "jtreg", - version: "7.2", + version: "7.3.1", build_number: "1", - file: "bundles/jtreg-7.2+1.zip", + file: "bundles/jtreg-7.3.1+1.zip", environment_name: "JT_HOME", environment_path: input.get("jtreg", "home_path") + "/bin", configure_args: "--with-jtreg=" + input.get("jtreg", "home_path"), diff -Nru openjdk-21-21.0.1+12/make/conf/version-numbers.conf openjdk-21-21.0.2+13/make/conf/version-numbers.conf --- openjdk-21-21.0.1+12/make/conf/version-numbers.conf 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/conf/version-numbers.conf 2024-01-16 16:19:00.000000000 +0000 @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=21 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=1 +DEFAULT_VERSION_UPDATE=2 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2023-10-17 +DEFAULT_VERSION_DATE=2024-01-16 DEFAULT_VERSION_CLASSFILE_MAJOR=65 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 diff -Nru openjdk-21-21.0.1+12/make/hotspot/gensrc/GensrcAdlc.gmk openjdk-21-21.0.2+13/make/hotspot/gensrc/GensrcAdlc.gmk --- openjdk-21-21.0.1+12/make/hotspot/gensrc/GensrcAdlc.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/hotspot/gensrc/GensrcAdlc.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -62,7 +62,7 @@ ADLC_CFLAGS += -I$(TOPDIR)/src/hotspot/share # Add file macro mappings - ADLC_CFLAGS += $(FILE_MACRO_CFLAGS) + ADLC_CFLAGS += $(FILE_MACRO_CFLAGS) $(REPRODUCIBLE_CFLAGS) ifeq ($(UBSAN_ENABLED), true) ADLC_CFLAGS += $(UBSAN_CFLAGS) @@ -133,6 +133,21 @@ ADLCFLAGS += -DARM=1 endif + # Set ASSERT, NDEBUG and PRODUCT flags just like in JvmFlags.gmk + ifeq ($(DEBUG_LEVEL), release) + # release builds disable uses of assert macro from . + ADLCFLAGS += -DNDEBUG + # For hotspot, release builds differ internally between "optimized" and "product" + # in that "optimize" does not define PRODUCT. + ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized) + ADLCFLAGS += -DPRODUCT + endif + else ifeq ($(DEBUG_LEVEL), fastdebug) + ADLCFLAGS += -DASSERT + else ifeq ($(DEBUG_LEVEL), slowdebug) + ADLCFLAGS += -DASSERT + endif + ############################################################################## # Concatenate all ad source files into a single file, which will be fed to # adlc. Also include a #line directive at the start of every included file diff -Nru openjdk-21-21.0.1+12/make/hotspot/lib/CompileJvm.gmk openjdk-21-21.0.2+13/make/hotspot/lib/CompileJvm.gmk --- openjdk-21-21.0.1+12/make/hotspot/lib/CompileJvm.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/hotspot/lib/CompileJvm.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -276,10 +276,10 @@ define SetupOperatorNewDeleteCheck $1.op_check: $1 $$(call ExecuteWithLog, $1.op_check, \ - $$(NM) $$< 2>&1 | $$(GREP) $$(addprefix -e , $$(MANGLED_SYMS)) | $$(GREP) $$(UNDEF_PATTERN) > $1.op_check || true) + $$(NM) $$(NMFLAGS) $$< 2>&1 | $$(GREP) $$(addprefix -e , $$(MANGLED_SYMS)) | $$(GREP) $$(UNDEF_PATTERN) > $1.op_check || true) if [ -s $1.op_check ]; then \ $$(ECHO) "$$(notdir $$<): Error: Use of global operators new and delete is not allowed in Hotspot:"; \ - $$(NM) $$< | $$(CXXFILT) | $$(EGREP) '$$(DEMANGLED_REGEXP)' | $$(GREP) $$(UNDEF_PATTERN); \ + $$(NM) $$(NMFLAGS) $$< | $$(CXXFILT) | $$(EGREP) '$$(DEMANGLED_REGEXP)' | $$(GREP) $$(UNDEF_PATTERN); \ $$(ECHO) "See: $$(TOPDIR)/make/hotspot/lib/CompileJvm.gmk"; \ exit 1; \ fi diff -Nru openjdk-21-21.0.1+12/make/hotspot/lib/JvmMapfile.gmk openjdk-21-21.0.2+13/make/hotspot/lib/JvmMapfile.gmk --- openjdk-21-21.0.1+12/make/hotspot/lib/JvmMapfile.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/hotspot/lib/JvmMapfile.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -53,7 +53,7 @@ # platform dependent. ifeq ($(call isTargetOs, linux), true) - DUMP_SYMBOLS_CMD := $(NM) --defined-only *$(OBJ_SUFFIX) + DUMP_SYMBOLS_CMD := $(NM) $(NMFLAGS) --defined-only *$(OBJ_SUFFIX) ifneq ($(FILTER_SYMBOLS_PATTERN), ) FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)| endif @@ -67,7 +67,7 @@ else ifeq ($(call isTargetOs, macosx), true) # nm on macosx prints out "warning: nm: no name list" to stderr for # files without symbols. Hide this, even at the expense of hiding real errors. - DUMP_SYMBOLS_CMD := $(NM) -Uj *$(OBJ_SUFFIX) 2> /dev/null + DUMP_SYMBOLS_CMD := $(NM) $(NMFLAGS) -Uj *$(OBJ_SUFFIX) 2> /dev/null ifneq ($(FILTER_SYMBOLS_PATTERN), ) FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)| endif @@ -89,7 +89,7 @@ # which may be installed under /opt/freeware/bin. So better use an absolute path here! # NM=/usr/bin/nm - DUMP_SYMBOLS_CMD := $(NM) -X64 -B -C *$(OBJ_SUFFIX) + DUMP_SYMBOLS_CMD := $(NM) $(NMFLAGS) -B -C *$(OBJ_SUFFIX) FILTER_SYMBOLS_AWK_SCRIPT := \ '{ \ if (($$2="d" || $$2="D") && ($$3 ~ /^__vft/ || $$3 ~ /^gHotSpotVM/)) print $$3; \ diff -Nru openjdk-21-21.0.1+12/make/hotspot/test/GtestImage.gmk openjdk-21-21.0.2+13/make/hotspot/test/GtestImage.gmk --- openjdk-21-21.0.1+12/make/hotspot/test/GtestImage.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/hotspot/test/GtestImage.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -61,7 +61,7 @@ $(eval $(call SetupCopyFiles, COPY_GTEST_PDB_$v, \ SRC := $(HOTSPOT_OUTPUTDIR)/variant-$v/libjvm/gtest, \ DEST := $(TEST_IMAGE_DIR)/hotspot/gtest/$v, \ - FILES := jvm.pdb gtestLauncher.pdb, \ + FILES := jvm.dll.pdb gtestLauncher.exe.pdb, \ )) \ $(eval TARGETS += $$(COPY_GTEST_PDB_$v)) \ ) \ diff -Nru openjdk-21-21.0.1+12/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java openjdk-21-21.0.2+13/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java --- openjdk-21-21.0.1+12/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java 2024-01-16 16:19:00.000000000 +0000 @@ -329,7 +329,7 @@ addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch"); addAttr(rv, "AssemblerListingLocation", outDir); addAttr(rv, "ObjectFileName", outDir+Util.sep); - addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb"); + addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.dll.pdb"); // Set /nologo option addAttr(rv, "SuppressStartupBanner", "true"); // Surpass the default /Tc or /Tp. @@ -409,7 +409,7 @@ addAttr(rv, "OutputFile", outDll); addAttr(rv, "SuppressStartupBanner", "true"); addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def"); - addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb"); + addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.dll.pdb"); addAttr(rv, "SubSystem", "Windows"); addAttr(rv, "BaseAddress", "0x8000000"); addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib"); diff -Nru openjdk-21-21.0.1+12/make/langtools/tools/javacserver/client/Client.java openjdk-21-21.0.2+13/make/langtools/tools/javacserver/client/Client.java --- openjdk-21-21.0.1+12/make/langtools/tools/javacserver/client/Client.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/langtools/tools/javacserver/client/Client.java 2024-01-16 16:19:00.000000000 +0000 @@ -51,9 +51,9 @@ public class Client { private static final Log.Level LOG_LEVEL = Log.Level.INFO; - // Wait 2 seconds for response, before giving up on javac server. - private static final int CONNECTION_TIMEOUT = 2000; - private static final int MAX_CONNECT_ATTEMPTS = 3; + // Wait 4 seconds for response, before giving up on javac server. + private static final int CONNECTION_TIMEOUT = 4000; + private static final int MAX_CONNECT_ATTEMPTS = 10; private static final int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000; private final ClientConfiguration conf; @@ -130,7 +130,7 @@ Log.error("Connection attempt failed: " + ex.getMessage()); if (attempt >= MAX_CONNECT_ATTEMPTS) { Log.error("Giving up"); - throw new IOException("Could not connect to server", ex); + throw new IOException("Could not connect to server after " + MAX_CONNECT_ATTEMPTS + " attempts with timeout " + CONNECTION_TIMEOUT, ex); } } Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS); diff -Nru openjdk-21-21.0.1+12/make/modules/java.base/gensrc/GensrcMisc.gmk openjdk-21-21.0.2+13/make/modules/java.base/gensrc/GensrcMisc.gmk --- openjdk-21-21.0.1+12/make/modules/java.base/gensrc/GensrcMisc.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/modules/java.base/gensrc/GensrcMisc.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -52,9 +52,7 @@ # Normalize OPENJDK_TARGET_CPU name to match jdk.internal.util.Architecture enum -ifneq ($(filter $(OPENJDK_TARGET_CPU), ppc64le), ) - OPENJDK_TARGET_ARCH_CANONICAL = ppc64 -else ifneq ($(filter $(OPENJDK_TARGET_CPU), s390x), ) +ifneq ($(filter $(OPENJDK_TARGET_CPU), s390x), ) OPENJDK_TARGET_ARCH_CANONICAL = s390 else ifneq ($(filter $(OPENJDK_TARGET_CPU), x86_64 amd64), ) OPENJDK_TARGET_ARCH_CANONICAL = x64 diff -Nru openjdk-21-21.0.1+12/make/modules/java.desktop/lib/Awt2dLibraries.gmk openjdk-21-21.0.2+13/make/modules/java.desktop/lib/Awt2dLibraries.gmk --- openjdk-21-21.0.1+12/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -469,11 +469,18 @@ # hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later. LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc + # list of disabled warnings and the compilers for which it was specifically added. + # array-bounds -> GCC 12 on Alpine Linux + # parentheses -> GCC 6 + # range-loop-analysis -> clang on Xcode12 + HARFBUZZ_DISABLED_WARNINGS_gcc := missing-field-initializers strict-aliasing \ - unused-result array-bounds + unused-result array-bounds parentheses # noexcept-type required for GCC 7 builds. Not required for GCC 8+. # expansion-to-defined required for GCC 9 builds. Not required for GCC 10+. - HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := class-memaccess noexcept-type expansion-to-defined dangling-reference + # maybe-uninitialized required for GCC 8 builds. Not required for GCC 9+. + HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := class-memaccess noexcept-type \ + expansion-to-defined dangling-reference maybe-uninitialized HARFBUZZ_DISABLED_WARNINGS_clang := missing-field-initializers range-loop-analysis HARFBUZZ_DISABLED_WARNINGS_microsoft := 4267 4244 diff -Nru openjdk-21-21.0.1+12/make/scripts/compare_exceptions.sh.incl openjdk-21-21.0.2+13/make/scripts/compare_exceptions.sh.incl --- openjdk-21-21.0.1+12/make/scripts/compare_exceptions.sh.incl 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/scripts/compare_exceptions.sh.incl 2024-01-16 16:19:00.000000000 +0000 @@ -49,8 +49,8 @@ SKIP_BIN_DIFF="true" SKIP_FULLDUMP_DIFF="true" ACCEPTED_JARZIP_CONTENTS=" - /modules_libs/java.security.jgss/w2k_lsa_auth.pdb - /modules_libs/java.security.jgss/w2k_lsa_auth.map + /modules_libs/java.security.jgss/w2k_lsa_auth.dll.pdb + /modules_libs/java.security.jgss/w2k_lsa_auth.dll.map /modules_libs/java.security.jgss/w2k_lsa_auth.dll " elif [ "$OPENJDK_TARGET_OS" = "macosx" ]; then diff -Nru openjdk-21-21.0.1+12/make/test/JtregNativeJdk.gmk openjdk-21-21.0.2+13/make/test/JtregNativeJdk.gmk --- openjdk-21-21.0.1+12/make/test/JtregNativeJdk.gmk 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/make/test/JtregNativeJdk.gmk 2024-01-16 16:19:00.000000000 +0000 @@ -132,6 +132,8 @@ # stripping during the test libraries' build. BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libFib := -g BUILD_JDK_JTREG_LIBRARIES_STRIP_SYMBOLS_libFib := false + # nio tests' libCreationTimeHelper native needs -ldl linker flag + BUILD_JDK_JTREG_LIBRARIES_LIBS_libCreationTimeHelper := -ldl endif ifeq ($(ASAN_ENABLED), true) diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/aarch64.ad openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/aarch64.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/aarch64.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/aarch64.ad 2024-01-16 16:19:00.000000000 +0000 @@ -3809,202 +3809,6 @@ __ br(target_reg); %} - enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ - C2_MacroAssembler _masm(&cbuf); - Register oop = as_Register($object$$reg); - Register box = as_Register($box$$reg); - Register disp_hdr = as_Register($tmp$$reg); - Register tmp = as_Register($tmp2$$reg); - Label cont; - Label object_has_monitor; - Label count, no_count; - - assert_different_registers(oop, box, tmp, disp_hdr); - - // Load markWord from object into displaced_header. - __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); - - if (DiagnoseSyncOnValueBasedClasses != 0) { - __ load_klass(tmp, oop); - __ ldrw(tmp, Address(tmp, Klass::access_flags_offset())); - __ tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS); - __ br(Assembler::NE, cont); - } - - // Check for existing monitor - __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); - - if (LockingMode == LM_MONITOR) { - __ tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0. - __ b(cont); - } else if (LockingMode == LM_LEGACY) { - // Set tmp to be (markWord of object | UNLOCK_VALUE). - __ orr(tmp, disp_hdr, markWord::unlocked_value); - - // Initialize the box. (Must happen before we update the object mark!) - __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); - - // Compare object markWord with an unlocked value (tmp) and if - // equal exchange the stack address of our box with object markWord. - // On failure disp_hdr contains the possibly locked markWord. - __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, - /*release*/ true, /*weak*/ false, disp_hdr); - __ br(Assembler::EQ, cont); - - assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); - - // If the compare-and-exchange succeeded, then we found an unlocked - // object, will have now locked it will continue at label cont - - // Check if the owner is self by comparing the value in the - // markWord of object (disp_hdr) with the stack pointer. - __ mov(rscratch1, sp); - __ sub(disp_hdr, disp_hdr, rscratch1); - __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); - // If condition is true we are cont and hence we can store 0 as the - // displaced header in the box, which indicates that it is a recursive lock. - __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result - __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); - __ b(cont); - } else { - assert(LockingMode == LM_LIGHTWEIGHT, "must be"); - __ fast_lock(oop, disp_hdr, tmp, rscratch1, no_count); - __ b(count); - } - - // Handle existing monitor. - __ bind(object_has_monitor); - - // The object's monitor m is unlocked iff m->owner == NULL, - // otherwise m->owner may contain a thread or a stack address. - // - // Try to CAS m->owner from NULL to current thread. - __ add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset())-markWord::monitor_value)); - __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, - /*release*/ true, /*weak*/ false, rscratch1); // Sets flags for result - - if (LockingMode != LM_LIGHTWEIGHT) { - // Store a non-null value into the box to avoid looking like a re-entrant - // lock. The fast-path monitor unlock code checks for - // markWord::monitor_value so use markWord::unused_mark which has the - // relevant bit set, and also matches ObjectSynchronizer::enter. - __ mov(tmp, (address)markWord::unused_mark().value()); - __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); - } - __ br(Assembler::EQ, cont); // CAS success means locking succeeded - - __ cmp(rscratch1, rthread); - __ br(Assembler::NE, cont); // Check for recursive locking - - // Recursive lock case - __ increment(Address(disp_hdr, in_bytes(ObjectMonitor::recursions_offset()) - markWord::monitor_value), 1); - // flag == EQ still from the cmp above, checking if this is a reentrant lock - - __ bind(cont); - // flag == EQ indicates success - // flag == NE indicates failure - __ br(Assembler::NE, no_count); - - __ bind(count); - __ increment(Address(rthread, JavaThread::held_monitor_count_offset())); - - __ bind(no_count); - %} - - enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ - C2_MacroAssembler _masm(&cbuf); - Register oop = as_Register($object$$reg); - Register box = as_Register($box$$reg); - Register disp_hdr = as_Register($tmp$$reg); - Register tmp = as_Register($tmp2$$reg); - Label cont; - Label object_has_monitor; - Label count, no_count; - - assert_different_registers(oop, box, tmp, disp_hdr); - - if (LockingMode == LM_LEGACY) { - // Find the lock address and load the displaced header from the stack. - __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); - - // If the displaced header is 0, we have a recursive unlock. - __ cmp(disp_hdr, zr); - __ br(Assembler::EQ, cont); - } - - // Handle existing monitor. - __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); - __ tbnz(tmp, exact_log2(markWord::monitor_value), object_has_monitor); - - if (LockingMode == LM_MONITOR) { - __ tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0. - __ b(cont); - } else if (LockingMode == LM_LEGACY) { - // Check if it is still a light weight lock, this is is true if we - // see the stack address of the basicLock in the markWord of the - // object. - - __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, - /*release*/ true, /*weak*/ false, tmp); - __ b(cont); - } else { - assert(LockingMode == LM_LIGHTWEIGHT, "must be"); - __ fast_unlock(oop, tmp, box, disp_hdr, no_count); - __ b(count); - } - - assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); - - // Handle existing monitor. - __ bind(object_has_monitor); - STATIC_ASSERT(markWord::monitor_value <= INT_MAX); - __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor - - if (LockingMode == LM_LIGHTWEIGHT) { - // If the owner is anonymous, we need to fix it -- in an outline stub. - Register tmp2 = disp_hdr; - __ ldr(tmp2, Address(tmp, ObjectMonitor::owner_offset())); - // We cannot use tbnz here, the target might be too far away and cannot - // be encoded. - __ tst(tmp2, (uint64_t)ObjectMonitor::ANONYMOUS_OWNER); - C2HandleAnonOMOwnerStub* stub = new (Compile::current()->comp_arena()) C2HandleAnonOMOwnerStub(tmp, tmp2); - Compile::current()->output()->add_stub(stub); - __ br(Assembler::NE, stub->entry()); - __ bind(stub->continuation()); - } - - __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); - - Label notRecursive; - __ cbz(disp_hdr, notRecursive); - - // Recursive lock - __ sub(disp_hdr, disp_hdr, 1u); - __ str(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); - __ cmp(disp_hdr, disp_hdr); // Sets flags for result - __ b(cont); - - __ bind(notRecursive); - __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset())); - __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset())); - __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. - __ cmp(rscratch1, zr); // Sets flags for result - __ cbnz(rscratch1, cont); - // need a release store here - __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset())); - __ stlr(zr, tmp); // set unowned - - __ bind(cont); - // flag == EQ indicates success - // flag == NE indicates failure - __ br(Assembler::NE, no_count); - - __ bind(count); - __ decrement(Address(rthread, JavaThread::held_monitor_count_offset())); - - __ bind(no_count); - %} - %} //----------FRAME-------------------------------------------------------------- @@ -16609,17 +16413,19 @@ // ============================================================================ // inlined locking and unlocking -instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) +instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3) %{ match(Set cr (FastLock object box)); - effect(TEMP tmp, TEMP tmp2); + effect(TEMP tmp, TEMP tmp2, TEMP tmp3); // TODO // identify correct cost ins_cost(5 * INSN_COST); format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} - ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); + ins_encode %{ + __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register); + %} ins_pipe(pipe_serial); %} @@ -16632,7 +16438,9 @@ ins_cost(5 * INSN_COST); format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} - ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); + ins_encode %{ + __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register); + %} ins_pipe(pipe_serial); %} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -434,7 +434,7 @@ if (LockingMode == LM_MONITOR) { __ b(*stub->entry()); } else { - __ unlock_object(r5, r4, r0, *stub->entry()); + __ unlock_object(r5, r4, r0, r6, *stub->entry()); } __ bind(*stub->continuation()); } @@ -2558,6 +2558,7 @@ Register obj = op->obj_opr()->as_register(); // may not be an oop Register hdr = op->hdr_opr()->as_register(); Register lock = op->lock_opr()->as_register(); + Register temp = op->scratch_opr()->as_register(); if (LockingMode == LM_MONITOR) { if (op->info() != nullptr) { add_debug_info_for_null_check_here(op->info()); @@ -2567,14 +2568,14 @@ } 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 - int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry()); + int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry()); if (op->info() != nullptr) { add_debug_info_for_null_check(null_check_offset, op->info()); } // done } else if (op->code() == lir_unlock) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); - __ unlock_object(hdr, obj, lock, *op->stub()->entry()); + __ unlock_object(hdr, obj, lock, temp, *op->stub()->entry()); } else { Unimplemented(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -314,6 +314,7 @@ // "lock" stores the address of the monitor stack slot, so this is not an oop LIR_Opr lock = new_register(T_INT); + LIR_Opr scratch = new_register(T_INT); CodeEmitInfo* info_for_exception = nullptr; if (x->needs_null_check()) { @@ -322,7 +323,7 @@ // this CodeEmitInfo must not have the xhandlers because here the // object is already locked (xhandlers expect object to be unlocked) CodeEmitInfo* info = state_for(x, x->state(), true); - monitor_enter(obj.result(), lock, syncTempOpr(), LIR_OprFact::illegalOpr, + monitor_enter(obj.result(), lock, syncTempOpr(), scratch, x->monitor_no(), info_for_exception, info); } @@ -335,8 +336,9 @@ LIR_Opr lock = new_register(T_INT); LIR_Opr obj_temp = new_register(T_INT); + LIR_Opr scratch = new_register(T_INT); set_no_result(x); - monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no()); + monitor_exit(obj_temp, lock, syncTempOpr(), scratch, x->monitor_no()); } void LIRGenerator::do_NegateOp(NegateOp* x) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -60,10 +60,10 @@ } } -int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { +int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) { const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); - assert_different_registers(hdr, obj, disp_hdr); + assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2); int null_check_offset = -1; verify_oop(obj); @@ -83,7 +83,7 @@ // Load object header ldr(hdr, Address(obj, hdr_offset)); if (LockingMode == LM_LIGHTWEIGHT) { - fast_lock(obj, hdr, rscratch1, rscratch2, slow_case); + lightweight_lock(obj, hdr, temp, rscratch2, slow_case); } else if (LockingMode == LM_LEGACY) { Label done; // and mark it as unlocked @@ -125,10 +125,10 @@ } -void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { +void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) { const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); - assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different"); + assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2); Label done; if (LockingMode != LM_LIGHTWEIGHT) { @@ -149,7 +149,7 @@ // be encoded. tst(hdr, markWord::monitor_value); br(Assembler::NE, slow_case); - fast_unlock(obj, hdr, rscratch1, rscratch2, slow_case); + lightweight_unlock(obj, hdr, temp, rscratch2, slow_case); } else if (LockingMode == LM_LEGACY) { // test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object - if the object header is not pointing to diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -58,14 +58,16 @@ // hdr : must be r0, contents destroyed // obj : must point to the object to lock, contents preserved // disp_hdr: must point to the displaced header location, contents preserved + // temp : temporary register, must not be rscratch1 or rscratch2 // returns code offset at which to add null check debug information - int lock_object (Register swap, Register obj, Register disp_hdr, Label& slow_case); + int lock_object (Register swap, Register obj, Register disp_hdr, Register temp, Label& slow_case); // unlocking // hdr : contents destroyed // obj : must point to the object to lock, contents preserved // disp_hdr: must be r0 & must point to the displaced header location, contents destroyed - void unlock_object(Register swap, Register obj, Register lock, Label& slow_case); + // temp : temporary register, must not be rscratch1 or rscratch2 + void unlock_object(Register swap, Register obj, Register lock, Register temp, Label& slow_case); void initialize_object( Register obj, // result: pointer to object after successful allocation diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -45,6 +45,202 @@ typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr); +void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register tmpReg, + Register tmp2Reg, Register tmp3Reg) { + Register oop = objectReg; + Register box = boxReg; + Register disp_hdr = tmpReg; + Register tmp = tmp2Reg; + Label cont; + Label object_has_monitor; + Label count, no_count; + + assert_different_registers(oop, box, tmp, disp_hdr); + + // Load markWord from object into displaced_header. + ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); + + if (DiagnoseSyncOnValueBasedClasses != 0) { + load_klass(tmp, oop); + ldrw(tmp, Address(tmp, Klass::access_flags_offset())); + tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS); + br(Assembler::NE, cont); + } + + // Check for existing monitor + tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); + + if (LockingMode == LM_MONITOR) { + tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0. + b(cont); + } else if (LockingMode == LM_LEGACY) { + // Set tmp to be (markWord of object | UNLOCK_VALUE). + orr(tmp, disp_hdr, markWord::unlocked_value); + + // Initialize the box. (Must happen before we update the object mark!) + str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); + + // Compare object markWord with an unlocked value (tmp) and if + // equal exchange the stack address of our box with object markWord. + // On failure disp_hdr contains the possibly locked markWord. + cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, + /*release*/ true, /*weak*/ false, disp_hdr); + br(Assembler::EQ, cont); + + assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + + // If the compare-and-exchange succeeded, then we found an unlocked + // object, will have now locked it will continue at label cont + + // Check if the owner is self by comparing the value in the + // markWord of object (disp_hdr) with the stack pointer. + mov(rscratch1, sp); + sub(disp_hdr, disp_hdr, rscratch1); + mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); + // If condition is true we are cont and hence we can store 0 as the + // displaced header in the box, which indicates that it is a recursive lock. + ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result + str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); + b(cont); + } else { + assert(LockingMode == LM_LIGHTWEIGHT, "must be"); + lightweight_lock(oop, disp_hdr, tmp, tmp3Reg, no_count); + b(count); + } + + // Handle existing monitor. + bind(object_has_monitor); + + // The object's monitor m is unlocked iff m->owner == NULL, + // otherwise m->owner may contain a thread or a stack address. + // + // Try to CAS m->owner from NULL to current thread. + add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset())-markWord::monitor_value)); + cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, + /*release*/ true, /*weak*/ false, rscratch1); // Sets flags for result + + if (LockingMode != LM_LIGHTWEIGHT) { + // Store a non-null value into the box to avoid looking like a re-entrant + // lock. The fast-path monitor unlock code checks for + // markWord::monitor_value so use markWord::unused_mark which has the + // relevant bit set, and also matches ObjectSynchronizer::enter. + mov(tmp, (address)markWord::unused_mark().value()); + str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); + } + br(Assembler::EQ, cont); // CAS success means locking succeeded + + cmp(rscratch1, rthread); + br(Assembler::NE, cont); // Check for recursive locking + + // Recursive lock case + increment(Address(disp_hdr, in_bytes(ObjectMonitor::recursions_offset()) - markWord::monitor_value), 1); + // flag == EQ still from the cmp above, checking if this is a reentrant lock + + bind(cont); + // flag == EQ indicates success + // flag == NE indicates failure + br(Assembler::NE, no_count); + + bind(count); + increment(Address(rthread, JavaThread::held_monitor_count_offset())); + + bind(no_count); +} + +void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Register tmpReg, + Register tmp2Reg) { + Register oop = objectReg; + Register box = boxReg; + Register disp_hdr = tmpReg; + Register tmp = tmp2Reg; + Label cont; + Label object_has_monitor; + Label count, no_count; + + assert_different_registers(oop, box, tmp, disp_hdr); + + if (LockingMode == LM_LEGACY) { + // Find the lock address and load the displaced header from the stack. + ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); + + // If the displaced header is 0, we have a recursive unlock. + cmp(disp_hdr, zr); + br(Assembler::EQ, cont); + } + + // Handle existing monitor. + ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); + tbnz(tmp, exact_log2(markWord::monitor_value), object_has_monitor); + + if (LockingMode == LM_MONITOR) { + tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0. + b(cont); + } else if (LockingMode == LM_LEGACY) { + // Check if it is still a light weight lock, this is is true if we + // see the stack address of the basicLock in the markWord of the + // object. + + cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, + /*release*/ true, /*weak*/ false, tmp); + b(cont); + } else { + assert(LockingMode == LM_LIGHTWEIGHT, "must be"); + lightweight_unlock(oop, tmp, box, disp_hdr, no_count); + b(count); + } + + assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + + // Handle existing monitor. + bind(object_has_monitor); + STATIC_ASSERT(markWord::monitor_value <= INT_MAX); + add(tmp, tmp, -(int)markWord::monitor_value); // monitor + + if (LockingMode == LM_LIGHTWEIGHT) { + // If the owner is anonymous, we need to fix it -- in an outline stub. + Register tmp2 = disp_hdr; + ldr(tmp2, Address(tmp, ObjectMonitor::owner_offset())); + // We cannot use tbnz here, the target might be too far away and cannot + // be encoded. + tst(tmp2, (uint64_t)ObjectMonitor::ANONYMOUS_OWNER); + C2HandleAnonOMOwnerStub* stub = new (Compile::current()->comp_arena()) C2HandleAnonOMOwnerStub(tmp, tmp2); + Compile::current()->output()->add_stub(stub); + br(Assembler::NE, stub->entry()); + bind(stub->continuation()); + } + + ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); + + Label notRecursive; + cbz(disp_hdr, notRecursive); + + // Recursive lock + sub(disp_hdr, disp_hdr, 1u); + str(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); + cmp(disp_hdr, disp_hdr); // Sets flags for result + b(cont); + + bind(notRecursive); + ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset())); + ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset())); + orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. + cmp(rscratch1, zr); // Sets flags for result + cbnz(rscratch1, cont); + // need a release store here + lea(tmp, Address(tmp, ObjectMonitor::owner_offset())); + stlr(zr, tmp); // set unowned + + bind(cont); + // flag == EQ indicates success + // flag == NE indicates failure + br(Assembler::NE, no_count); + + bind(count); + decrement(Address(rthread, JavaThread::held_monitor_count_offset())); + + bind(no_count); +} + // Search for str1 in str2 and return index or -1 // Clobbers: rscratch1, rscratch2, rflags. May also clobber v0-v1, when icnt1==-1. void C2_MacroAssembler::string_indexof(Register str2, Register str1, diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -35,6 +35,11 @@ enum shift_kind kind = Assembler::LSL, unsigned shift = 0); public: + // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file. + // See full description in macroAssembler_aarch64.cpp. + void fast_lock(Register object, Register box, Register tmp, Register tmp2, Register tmp3); + void fast_unlock(Register object, Register box, Register tmp, Register tmp2); + void string_compare(Register str1, Register str2, Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2, FloatRegister vtmp1, diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1290,6 +1290,9 @@ return test_and_branch_to_trampoline_delta < test_and_branch_delta_limit; } +ZLoadBarrierStubC2Aarch64::ZLoadBarrierStubC2Aarch64(const MachNode* node, Address ref_addr, Register ref) + : ZLoadBarrierStubC2(node, ref_addr, ref), _test_and_branch_reachable_entry(), _offset(), _deferred_emit(false), _test_and_branch_reachable(false) {} + ZLoadBarrierStubC2Aarch64::ZLoadBarrierStubC2Aarch64(const MachNode* node, Address ref_addr, Register ref, int offset) : ZLoadBarrierStubC2(node, ref_addr, ref), _test_and_branch_reachable_entry(), _offset(offset), _deferred_emit(false), _test_and_branch_reachable(false) { PhaseOutput* const output = Compile::current()->output(); @@ -1319,6 +1322,12 @@ return cb.insts_size(); } +ZLoadBarrierStubC2Aarch64* ZLoadBarrierStubC2Aarch64::create(const MachNode* node, Address ref_addr, Register ref) { + ZLoadBarrierStubC2Aarch64* const stub = new (Compile::current()->comp_arena()) ZLoadBarrierStubC2Aarch64(node, ref_addr, ref); + register_stub(stub); + return stub; +} + ZLoadBarrierStubC2Aarch64* ZLoadBarrierStubC2Aarch64::create(const MachNode* node, Address ref_addr, Register ref, int offset) { ZLoadBarrierStubC2Aarch64* const stub = new (Compile::current()->comp_arena()) ZLoadBarrierStubC2Aarch64(node, ref_addr, ref, offset); register_stub(stub); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -265,10 +265,12 @@ bool _deferred_emit; bool _test_and_branch_reachable; + ZLoadBarrierStubC2Aarch64(const MachNode* node, Address ref_addr, Register ref); ZLoadBarrierStubC2Aarch64(const MachNode* node, Address ref_addr, Register ref, int offset); int get_stub_size(); public: + static ZLoadBarrierStubC2Aarch64* create(const MachNode* node, Address ref_addr, Register ref); static ZLoadBarrierStubC2Aarch64* create(const MachNode* node, Address ref_addr, Register ref, int offset); virtual void emit_code(MacroAssembler& masm); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad 2024-01-16 16:19:00.000000000 +0000 @@ -48,7 +48,7 @@ __ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatMarkBadBeforeMov); __ movzw(tmp, barrier_Relocation::unpatched); __ tst(ref, tmp); - ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref); + ZLoadBarrierStubC2Aarch64* const stub = ZLoadBarrierStubC2Aarch64::create(node, ref_addr, ref); __ br(Assembler::NE, *stub->entry()); z_uncolor(_masm, node, ref); __ bind(*stub->continuation()); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -622,7 +622,7 @@ // Check that all monitors are unlocked { Label loop, exception, entry, restart; - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); const Address monitor_block_top( rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( @@ -692,6 +692,12 @@ // testing if reserved zone needs to be re-enabled Label no_reserved_zone_enabling; + // check if already enabled - if so no re-enabling needed + assert(sizeof(StackOverflow::StackGuardState) == 4, "unexpected size"); + ldrw(rscratch1, Address(rthread, JavaThread::stack_guard_state_offset())); + cmpw(rscratch1, (u1)StackOverflow::stack_guard_enabled); + br(Assembler::EQ, no_reserved_zone_enabling); + // look for an overflow into the stack reserved zone, i.e. // interpreter_frame_sender_sp <= JavaThread::reserved_stack_activation ldr(rscratch1, Address(rthread, JavaThread::reserved_stack_activation_offset())); @@ -725,7 +731,7 @@ // // Kills: // r0 -// c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs) +// c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, .. (param regs) // rscratch1, rscratch2 (scratch regs) void InterpreterMacroAssembler::lock_object(Register lock_reg) { @@ -740,6 +746,8 @@ const Register swap_reg = r0; const Register tmp = c_rarg2; const Register obj_reg = c_rarg3; // Will contain the oop + const Register tmp2 = c_rarg4; + const Register tmp3 = c_rarg5; const int obj_offset = in_bytes(BasicObjectLock::obj_offset()); const int lock_offset = in_bytes(BasicObjectLock::lock_offset()); @@ -760,7 +768,7 @@ if (LockingMode == LM_LIGHTWEIGHT) { ldr(tmp, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - fast_lock(obj_reg, tmp, rscratch1, rscratch2, slow_case); + lightweight_lock(obj_reg, tmp, tmp2, tmp3, slow_case); b(count); } else if (LockingMode == LM_LEGACY) { // Load (object->mark() | 1) into swap_reg @@ -858,6 +866,7 @@ const Register swap_reg = r0; const Register header_reg = c_rarg2; // Will contain the old oopMark const Register obj_reg = c_rarg3; // Will contain the oop + const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock save_bcp(); // Save in case of exception @@ -891,7 +900,7 @@ ldr(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); tbnz(header_reg, exact_log2(markWord::monitor_value), slow_case); - fast_unlock(obj_reg, header_reg, swap_reg, rscratch1, slow_case); + lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case); b(count); bind(slow_case); } else if (LockingMode == LM_LEGACY) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2737,6 +2737,10 @@ mov(result, expected); lse_cas(result, new_val, addr, size, acquire, release, /*not_pair*/ true); compare_eq(result, expected, size); +#ifdef ASSERT + // Poison rscratch1 which is written on !UseLSE branch + mov(rscratch1, 0x1f1f1f1f1f1f1f1f); +#endif } else { Label retry_load, done; prfm(Address(addr), PSTL1STRM); @@ -6212,16 +6216,16 @@ } } -// Implements fast-locking. +// Implements lightweight-locking. // Branches to slow upon failure to lock the object, with ZF cleared. // Falls through upon success with ZF set. // // - obj: the object to be locked // - hdr: the header, already loaded from obj, will be destroyed // - t1, t2: temporary registers, will be destroyed -void MacroAssembler::fast_lock(Register obj, Register hdr, Register t1, Register t2, Label& slow) { +void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register t1, Register t2, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); - assert_different_registers(obj, hdr, t1, t2); + assert_different_registers(obj, hdr, t1, t2, rscratch1); // Check if we would have space on lock-stack for the object. ldrw(t1, Address(rthread, JavaThread::lock_stack_top_offset())); @@ -6233,6 +6237,7 @@ // Clear lock-bits, into t2 eor(t2, hdr, markWord::unlocked_value); // Try to swing header from unlocked to locked + // Clobbers rscratch1 when UseLSE is false cmpxchg(/*addr*/ obj, /*expected*/ hdr, /*new*/ t2, Assembler::xword, /*acquire*/ true, /*release*/ true, /*weak*/ false, t1); br(Assembler::NE, slow); @@ -6244,16 +6249,16 @@ strw(t1, Address(rthread, JavaThread::lock_stack_top_offset())); } -// Implements fast-unlocking. +// Implements lightweight-unlocking. // Branches to slow upon failure, with ZF cleared. // Falls through upon success, with ZF set. // // - obj: the object to be unlocked // - hdr: the (pre-loaded) header of the object // - t1, t2: temporary registers -void MacroAssembler::fast_unlock(Register obj, Register hdr, Register t1, Register t2, Label& slow) { +void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Register t1, Register t2, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); - assert_different_registers(obj, hdr, t1, t2); + assert_different_registers(obj, hdr, t1, t2, rscratch1); #ifdef ASSERT { @@ -6293,6 +6298,7 @@ orr(t1, hdr, markWord::unlocked_value); // Try to swing header from locked to unlocked + // Clobbers rscratch1 when UseLSE is false cmpxchg(obj, hdr, t1, Assembler::xword, /*acquire*/ true, /*release*/ true, /*weak*/ false, t2); br(Assembler::NE, slow); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -1582,8 +1582,8 @@ // Code for java.lang.Thread::onSpinWait() intrinsic. void spin_wait(); - void fast_lock(Register obj, Register hdr, Register t1, Register t2, Label& slow); - void fast_unlock(Register obj, Register hdr, Register t1, Register t2, Label& slow); + void lightweight_lock(Register obj, Register hdr, Register t1, Register t2, Label& slow); + void lightweight_unlock(Register obj, Register hdr, Register t1, Register t2, Label& slow); private: // Check the current thread doesn't need a cross modify fence. diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1759,6 +1759,7 @@ const Register obj_reg = r19; // Will contain the oop const Register lock_reg = r13; // Address of compiler lock object (BasicLock) const Register old_hdr = r13; // value of old header at unlock time + const Register lock_tmp = r14; // Temporary used by lightweight_lock/unlock const Register tmp = lr; Label slow_path_lock; @@ -1812,7 +1813,7 @@ } else { assert(LockingMode == LM_LIGHTWEIGHT, "must be"); __ ldr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ fast_lock(obj_reg, swap_reg, tmp, rscratch1, slow_path_lock); + __ lightweight_lock(obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock); } __ bind(count); __ increment(Address(rthread, JavaThread::held_monitor_count_offset())); @@ -1953,7 +1954,7 @@ assert(LockingMode == LM_LIGHTWEIGHT, ""); __ ldr(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes())); __ tbnz(old_hdr, exact_log2(markWord::monitor_value), slow_path_unlock); - __ fast_unlock(obj_reg, old_hdr, swap_reg, rscratch1, slow_path_unlock); + __ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock); __ decrement(Address(rthread, JavaThread::held_monitor_count_offset())); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -688,7 +688,7 @@ // monitor entry size: see picture of stack set // (generate_method_entry) and frame_amd64.hpp - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); // total overhead size: entry_size + (saved rbp through expr stack // bottom). be sure to change this if you add/subtract anything @@ -769,7 +769,7 @@ const Address monitor_block_top( rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); #ifdef ASSERT { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3813,7 +3813,7 @@ rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( rfp, frame::interpreter_frame_initial_sp_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); Label allocated; @@ -3916,7 +3916,7 @@ rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( rfp, frame::interpreter_frame_initial_sp_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); Label found; diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -219,7 +219,7 @@ Register t2 = hdr; // blow Register t3 = Rtemp; // blow - fast_lock_2(obj /* obj */, t1, t2, t3, 1 /* savemask - save t1 */, slow_case); + lightweight_lock(obj /* obj */, t1, t2, t3, 1 /* savemask - save t1 */, slow_case); // Success: fall through } else if (LockingMode == LM_LEGACY) { @@ -282,8 +282,8 @@ Register t2 = hdr; // blow Register t3 = Rtemp; // blow - fast_unlock_2(obj /* object */, t1, t2, t3, 1 /* savemask (save t1) */, - slow_case); + lightweight_unlock(obj /* object */, t1, t2, t3, 1 /* savemask (save t1) */, + slow_case); // Success: Fall through } else if (LockingMode == LM_LEGACY) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -93,8 +93,8 @@ if (LockingMode == LM_LIGHTWEIGHT) { - fast_lock_2(Roop /* obj */, Rbox /* t1 */, Rscratch /* t2 */, Rscratch2 /* t3 */, - 1 /* savemask (save t1) */, done); + lightweight_lock(Roop /* obj */, Rbox /* t1 */, Rscratch /* t2 */, Rscratch2 /* t3 */, + 1 /* savemask (save t1) */, done); // Success: set Z cmp(Roop, Roop); @@ -143,8 +143,8 @@ if (LockingMode == LM_LIGHTWEIGHT) { - fast_unlock_2(Roop /* obj */, Rbox /* t1 */, Rscratch /* t2 */, Rscratch2 /* t3 */, - 1 /* savemask (save t1) */, done); + lightweight_unlock(Roop /* obj */, Rbox /* t1 */, Rscratch /* t2 */, Rscratch2 /* t3 */, + 1 /* savemask (save t1) */, done); cmp(Roop, Roop); // Success: Set Z // Fall through diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/frame_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/frame_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/frame_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/frame_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -279,7 +279,6 @@ return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset); } -// Pointer beyond the "oldest/deepest" BasicObjectLock on stack. BasicObjectLock* frame::interpreter_frame_monitor_end() const { BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset); // make sure the pointer points inside the frame diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/interp_masm_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/interp_masm_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/interp_masm_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/interp_masm_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -814,7 +814,7 @@ { Label loop; - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); const Register Rbottom = R3; const Register Rcur_obj = Rtemp; @@ -911,7 +911,7 @@ } if (LockingMode == LM_LIGHTWEIGHT) { - fast_lock_2(Robj, R0 /* t1 */, Rmark /* t2 */, Rtemp /* t3 */, 0 /* savemask */, slow_case); + lightweight_lock(Robj, R0 /* t1 */, Rmark /* t2 */, Rtemp /* t3 */, 0 /* savemask */, slow_case); b(done); } else if (LockingMode == LM_LEGACY) { // On MP platforms the next load could return a 'stale' value if the memory location has been modified by another thread. @@ -1033,8 +1033,8 @@ cmpoop(Rtemp, Robj); b(slow_case, ne); - fast_unlock_2(Robj /* obj */, Rlock /* t1 */, Rmark /* t2 */, Rtemp /* t3 */, - 1 /* savemask (save t1) */, slow_case); + lightweight_unlock(Robj /* obj */, Rlock /* t1 */, Rmark /* t2 */, Rtemp /* t3 */, + 1 /* savemask (save t1) */, slow_case); b(done); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/macroAssembler_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/macroAssembler_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/macroAssembler_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/macroAssembler_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1748,14 +1748,14 @@ POISON_REG(mask, 1, R2, poison) \ POISON_REG(mask, 2, R3, poison) -// Attempt to fast-lock an object +// Attempt to lightweight-lock an object // Registers: // - obj: the object to be locked // - t1, t2, t3: temp registers. If corresponding bit in savemask is set, they get saved, otherwise blown. // Result: // - Success: fallthrough // - Error: break to slow, Z cleared. -void MacroAssembler::fast_lock_2(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow) { +void MacroAssembler::lightweight_lock(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); assert_different_registers(obj, t1, t2, t3); @@ -1806,14 +1806,14 @@ // Success: fall through } -// Attempt to fast-unlock an object +// Attempt to lightweight-unlock an object // Registers: // - obj: the object to be unlocked // - t1, t2, t3: temp registers. If corresponding bit in savemask is set, they get saved, otherwise blown. // Result: // - Success: fallthrough // - Error: break to slow, Z cleared. -void MacroAssembler::fast_unlock_2(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow) { +void MacroAssembler::lightweight_unlock(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); assert_different_registers(obj, t1, t2, t3); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/macroAssembler_arm.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/macroAssembler_arm.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/macroAssembler_arm.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/macroAssembler_arm.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -1009,23 +1009,23 @@ void cas_for_lock_acquire(Register oldval, Register newval, Register base, Register tmp, Label &slow_case, bool allow_fallthrough_on_failure = false, bool one_shot = false); void cas_for_lock_release(Register oldval, Register newval, Register base, Register tmp, Label &slow_case, bool allow_fallthrough_on_failure = false, bool one_shot = false); - // Attempt to fast-lock an object + // Attempt to lightweight-lock an object // Registers: // - obj: the object to be locked // - t1, t2, t3: temp registers. If corresponding bit in savemask is set, they get saved, otherwise blown. // Result: // - Success: fallthrough // - Error: break to slow, Z cleared. - void fast_lock_2(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow); + void lightweight_lock(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow); - // Attempt to fast-unlock an object + // Attempt to lightweight-unlock an object // Registers: // - obj: the object to be unlocked // - t1, t2, t3: temp registers. If corresponding bit in savemask is set, they get saved, otherwise blown. // Result: // - Success: fallthrough // - Error: break to slow, Z cleared. - void fast_unlock_2(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow); + void lightweight_unlock(Register obj, Register t1, Register t2, Register t3, unsigned savemask, Label& slow); #ifndef PRODUCT // Preserves flags and all registers. diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/sharedRuntime_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/sharedRuntime_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/sharedRuntime_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/sharedRuntime_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1155,8 +1155,8 @@ if (LockingMode == LM_LIGHTWEIGHT) { log_trace(fastlock)("SharedRuntime lock fast"); - __ fast_lock_2(sync_obj /* object */, disp_hdr /* t1 */, tmp /* t2 */, Rtemp /* t3 */, - 0x7 /* savemask */, slow_lock); + __ lightweight_lock(sync_obj /* object */, disp_hdr /* t1 */, tmp /* t2 */, Rtemp /* t3 */, + 0x7 /* savemask */, slow_lock); // Fall through to lock_done } else if (LockingMode == LM_LEGACY) { const Register mark = tmp; @@ -1242,8 +1242,8 @@ if (method->is_synchronized()) { if (LockingMode == LM_LIGHTWEIGHT) { log_trace(fastlock)("SharedRuntime unlock fast"); - __ fast_unlock_2(sync_obj, R2 /* t1 */, tmp /* t2 */, Rtemp /* t3 */, - 7 /* savemask */, slow_unlock); + __ lightweight_unlock(sync_obj, R2 /* t1 */, tmp /* t2 */, Rtemp /* t3 */, + 7 /* savemask */, slow_unlock); // Fall through } else if (LockingMode == LM_LEGACY) { // See C1_MacroAssembler::unlock_object() for more comments diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -530,7 +530,7 @@ const Register RmaxStack = R2; // monitor entry size - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); // total overhead size: entry_size + (saved registers, thru expr stack bottom). // be sure to change this if you add/subtract anything to/from the overhead area @@ -569,7 +569,7 @@ void TemplateInterpreterGenerator::lock_method() { // synchronize method - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); assert ((entry_size % StackAlignmentInBytes) == 0, "should keep stack alignment"); #ifdef ASSERT diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/arm/templateTable_arm.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/arm/templateTable_arm.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/arm/templateTable_arm.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/arm/templateTable_arm.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -4270,7 +4270,7 @@ // check for null object __ null_check(Robj, Rtemp); - const int entry_size = (frame::interpreter_frame_monitor_size() * wordSize); + const int entry_size = (frame::interpreter_frame_monitor_size_in_bytes()); assert (entry_size % StackAlignmentInBytes == 0, "keep stack alignment"); Label allocate_monitor, allocated; @@ -4381,7 +4381,7 @@ // check for null object __ null_check(Robj, Rtemp); - const int entry_size = (frame::interpreter_frame_monitor_size() * wordSize); + const int entry_size = (frame::interpreter_frame_monitor_size_in_bytes()); Label found, throw_exception; // find matching slot diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3141,7 +3141,7 @@ // Klass seen before, nothing to do (regardless of unknown bit). //beq(CCR1, do_nothing); - __ andi_(R0, klass, TypeEntries::type_unknown); + __ andi_(R0, tmp, TypeEntries::type_unknown); // Already unknown. Nothing to do anymore. //bne(CCR0, do_nothing); __ crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -115,7 +115,7 @@ } if (LockingMode == LM_LIGHTWEIGHT) { - fast_lock(Roop, Rmark, Rscratch, slow_int); + lightweight_lock(Roop, Rmark, Rscratch, slow_int); } else if (LockingMode == LM_LEGACY) { // ... and mark it unlocked. ori(Rmark, Rmark, markWord::unlocked_value); @@ -181,7 +181,7 @@ ld(Rmark, oopDesc::mark_offset_in_bytes(), Roop); andi_(R0, Rmark, markWord::monitor_value); bne(CCR0, slow_int); - fast_unlock(Roop, Rmark, slow_int); + lightweight_unlock(Roop, Rmark, slow_int); } else if (LockingMode == LM_LEGACY) { // Check if it is still a light weight lock, this is is true if we see // the stack address of the basicLock in the markWord of the object. diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/frame_ppc.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/frame_ppc.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/frame_ppc.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/frame_ppc.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -454,7 +454,6 @@ frame::frame(void* sp, void* fp, void* pc) : frame((intptr_t*)sp, (address)pc) {} #endif -// Pointer beyond the "oldest/deepest" BasicObjectLock on stack. BasicObjectLock* frame::interpreter_frame_monitor_end() const { BasicObjectLock* result = (BasicObjectLock*) at(ijava_idx(monitors)); // make sure the pointer points inside the frame diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/frame_ppc.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/frame_ppc.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/frame_ppc.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/frame_ppc.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -424,9 +424,6 @@ template static void update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr); - // Size of a monitor in bytes. - static int interpreter_frame_monitor_size_in_bytes(); - // The size of a cInterpreter object. static inline int interpreter_frame_cinterpreterstate_size_in_bytes(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/frame_ppc.inline.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/frame_ppc.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/frame_ppc.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/frame_ppc.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -250,10 +250,6 @@ WordsPerLong); // number of stack slots for a Java long } -inline int frame::interpreter_frame_monitor_size_in_bytes() { - return frame::interpreter_frame_monitor_size() * wordSize; -} - // entry frames inline intptr_t* frame::entry_frame_argument_at(int offset) const { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -887,6 +887,12 @@ // Test if reserved zone needs to be enabled. Label no_reserved_zone_enabling; + // check if already enabled - if so no re-enabling needed + assert(sizeof(StackOverflow::StackGuardState) == 4, "unexpected size"); + lwz(R0, in_bytes(JavaThread::stack_guard_state_offset()), R16_thread); + cmpwi(CCR0, R0, StackOverflow::stack_guard_enabled); + beq_predict_taken(CCR0, no_reserved_zone_enabling); + // Compare frame pointers. There is no good stack pointer, as with stack // frame compression we can get different SPs when we do calls. A subsequent // call could have a smaller SP, so that this compare succeeds for an @@ -961,7 +967,7 @@ } if (LockingMode == LM_LIGHTWEIGHT) { - fast_lock(object, /* mark word */ header, tmp, slow_case); + lightweight_lock(object, /* mark word */ header, tmp, slow_case); b(count_locking); } else if (LockingMode == LM_LEGACY) { @@ -1111,7 +1117,7 @@ ld(header, oopDesc::mark_offset_in_bytes(), object); andi_(R0, header, markWord::monitor_value); bne(CCR0, slow_case); - fast_unlock(object, header, slow_case); + lightweight_unlock(object, header, slow_case); } else { addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes()); @@ -1777,7 +1783,7 @@ // Klass seen before, nothing to do (regardless of unknown bit). //beq(CCR1, do_nothing); - andi_(R0, klass, TypeEntries::type_unknown); + andi_(R0, tmp, TypeEntries::type_unknown); // Already unknown. Nothing to do anymore. //bne(CCR0, do_nothing); crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne @@ -1976,7 +1982,7 @@ } } -// Add a InterpMonitorElem to stack (see frame_sparc.hpp). +// Add a monitor (see frame_ppc.hpp). void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) { // Very-local scratch registers. diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2707,7 +2707,7 @@ b(failure); } else { assert(LockingMode == LM_LIGHTWEIGHT, "must be"); - fast_lock(oop, displaced_header, temp, failure); + lightweight_lock(oop, displaced_header, temp, failure); b(success); } @@ -2819,7 +2819,7 @@ b(success); } else { assert(LockingMode == LM_LIGHTWEIGHT, "must be"); - fast_unlock(oop, current_header, failure); + lightweight_unlock(oop, current_header, failure); b(success); } @@ -4491,14 +4491,14 @@ } } -// Implements fast-locking. +// Implements lightweight-locking. // Branches to slow upon failure to lock the object, with CCR0 NE. // Falls through upon success with CCR0 EQ. // // - obj: the object to be locked // - hdr: the header, already loaded from obj, will be destroyed // - t1: temporary register -void MacroAssembler::fast_lock(Register obj, Register hdr, Register t1, Label& slow) { +void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register t1, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); assert_different_registers(obj, hdr, t1); @@ -4524,13 +4524,13 @@ stw(t1, in_bytes(JavaThread::lock_stack_top_offset()), R16_thread); } -// Implements fast-unlocking. +// Implements lightweight-unlocking. // Branches to slow upon failure, with CCR0 NE. // Falls through upon success, with CCR0 EQ. // // - obj: the object to be unlocked // - hdr: the (pre-loaded) header of the object, will be destroyed -void MacroAssembler::fast_unlock(Register obj, Register hdr, Label& slow) { +void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); assert_different_registers(obj, hdr); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -607,8 +607,8 @@ void inc_held_monitor_count(Register tmp); void dec_held_monitor_count(Register tmp); void atomically_flip_locked_state(bool is_unlock, Register obj, Register tmp, Label& failed, int semantics); - void fast_lock(Register obj, Register hdr, Register t1, Label& slow); - void fast_unlock(Register obj, Register hdr, Label& slow); + void lightweight_lock(Register obj, Register hdr, Register t1, Label& slow); + void lightweight_unlock(Register obj, Register hdr, Label& slow); // allocation (for C1) void tlab_allocate( diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2457,7 +2457,6 @@ // -------------------------------------------------------------------------- if (method->is_synchronized()) { - ConditionRegister r_flag = CCR1; Register r_oop = r_temp_4; const Register r_box = r_temp_5; Label done, locked; @@ -2472,8 +2471,8 @@ // Try fastpath for locking. // fast_lock kills r_temp_1, r_temp_2, r_temp_3. - __ compiler_fast_lock_object(r_flag, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); - __ beq(r_flag, locked); + __ compiler_fast_lock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); + __ beq(CCR0, locked); // None of the above fast optimizations worked so we have to get into the // slow case of monitor enter. Inline a special case of call_VM that @@ -2666,8 +2665,6 @@ // -------------------------------------------------------------------------- if (method->is_synchronized()) { - - ConditionRegister r_flag = CCR1; const Register r_oop = r_temp_4; const Register r_box = r_temp_5; const Register r_exception = r_temp_6; @@ -2684,8 +2681,8 @@ __ addi(r_box, R1_SP, lock_offset); // Try fastpath for unlocking. - __ compiler_fast_unlock_object(r_flag, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); - __ beq(r_flag, done); + __ compiler_fast_unlock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); + __ beq(CCR0, done); // Save and restore any potential method result value around the unlocking operation. save_native_result(masm, ret_type, workspace_slot_offset); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -4106,79 +4106,67 @@ // at next monitor exit. void TemplateTable::monitorenter() { transition(atos, vtos); - __ verify_oop(R17_tos); - Register Rcurrent_monitor = R11_scratch1, - Rcurrent_obj = R12_scratch2, + Register Rcurrent_monitor = R3_ARG1, + Rcurrent_obj = R4_ARG2, Robj_to_lock = R17_tos, - Rscratch1 = R3_ARG1, - Rscratch2 = R4_ARG2, - Rscratch3 = R5_ARG3, - Rcurrent_obj_addr = R6_ARG4; + Rscratch1 = R11_scratch1, + Rscratch2 = R12_scratch2, + Rbot = R5_ARG3, + Rfree_slot = R6_ARG4; + + Label Lfound, Lallocate_new; + + __ ld(Rscratch1, _abi0(callers_sp), R1_SP); // load FP + __ li(Rfree_slot, 0); // Points to free slot or null. + + // Set up search loop - start with topmost monitor. + __ mr(Rcurrent_monitor, R26_monitor); + __ addi(Rbot, Rscratch1, -frame::ijava_state_size); // ------------------------------------------------------------------------------ // Null pointer exception. - __ null_check_throw(Robj_to_lock, -1, R11_scratch1); + __ null_check_throw(Robj_to_lock, -1, Rscratch1); - // Try to acquire a lock on the object. - // Repeat until succeeded (i.e., until monitorenter returns true). + // Check if any slot is present => short cut to allocation if not. + __ cmpld(CCR0, Rcurrent_monitor, Rbot); + __ beq(CCR0, Lallocate_new); // ------------------------------------------------------------------------------ // Find a free slot in the monitor block. - Label Lfound, Lexit, Lallocate_new; - ConditionRegister found_free_slot = CCR0, - found_same_obj = CCR1, - reached_limit = CCR6; + // Note: The order of the monitors is important for C2 OSR which derives the + // unlock order from it (see comments for interpreter_frame_monitor_*). { - Label Lloop; - Register Rlimit = Rcurrent_monitor; + Label Lloop, LnotFree, Lexit; - // Set up search loop - start with topmost monitor. - __ addi(Rcurrent_obj_addr, R26_monitor, in_bytes(BasicObjectLock::obj_offset())); - - __ ld(Rlimit, 0, R1_SP); - __ addi(Rlimit, Rlimit, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes() - in_bytes(BasicObjectLock::obj_offset()))); // Monitor base - - // Check if any slot is present => short cut to allocation if not. - __ cmpld(reached_limit, Rcurrent_obj_addr, Rlimit); - __ bgt(reached_limit, Lallocate_new); - - // Pre-load topmost slot. - __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr); - __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize); - // The search loop. __ bind(Lloop); - // Found free slot? - __ cmpdi(found_free_slot, Rcurrent_obj, 0); - // Is this entry for same obj? If so, stop the search and take the found - // free slot or allocate a new one to enable recursive locking. - __ cmpd(found_same_obj, Rcurrent_obj, Robj_to_lock); - __ cmpld(reached_limit, Rcurrent_obj_addr, Rlimit); - __ beq(found_free_slot, Lexit); - __ beq(found_same_obj, Lallocate_new); - __ bgt(reached_limit, Lallocate_new); - // Check if last allocated BasicLockObj reached. - __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr); - __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize); - // Next iteration if unchecked BasicObjectLocks exist on the stack. - __ b(Lloop); + __ ld(Rcurrent_obj, in_bytes(BasicObjectLock::obj_offset()), Rcurrent_monitor); + // Exit if current entry is for same object; this guarantees, that new monitor + // used for recursive lock is above the older one. + __ cmpd(CCR0, Rcurrent_obj, Robj_to_lock); + __ beq(CCR0, Lexit); // recursive locking + + __ cmpdi(CCR0, Rcurrent_obj, 0); + __ bne(CCR0, LnotFree); + __ mr(Rfree_slot, Rcurrent_monitor); // remember free slot closest to the bottom + __ bind(LnotFree); + + __ addi(Rcurrent_monitor, Rcurrent_monitor, frame::interpreter_frame_monitor_size_in_bytes()); + __ cmpld(CCR0, Rcurrent_monitor, Rbot); + __ bne(CCR0, Lloop); + __ bind(Lexit); } // ------------------------------------------------------------------------------ // Check if we found a free slot. - __ bind(Lexit); - - __ addi(Rcurrent_monitor, Rcurrent_obj_addr, -(frame::interpreter_frame_monitor_size() * wordSize) - in_bytes(BasicObjectLock::obj_offset())); - __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, - frame::interpreter_frame_monitor_size() * wordSize); - __ b(Lfound); + __ cmpdi(CCR0, Rfree_slot, 0); + __ bne(CCR0, Lfound); // We didn't find a free BasicObjLock => allocate one. - __ align(32, 12); __ bind(Lallocate_new); __ add_monitor_to_stack(false, Rscratch1, Rscratch2); - __ mr(Rcurrent_monitor, R26_monitor); - __ addi(Rcurrent_obj_addr, R26_monitor, in_bytes(BasicObjectLock::obj_offset())); + __ mr(Rfree_slot, R26_monitor); // ------------------------------------------------------------------------------ // We now have a slot to lock. @@ -4188,8 +4176,8 @@ // The object has already been popped from the stack, so the expression stack looks correct. __ addi(R14_bcp, R14_bcp, 1); - __ std(Robj_to_lock, 0, Rcurrent_obj_addr); - __ lock_object(Rcurrent_monitor, Robj_to_lock); + __ std(Robj_to_lock, in_bytes(BasicObjectLock::obj_offset()), Rfree_slot); + __ lock_object(Rfree_slot, Robj_to_lock); // Check if there's enough space on the stack for the monitors after locking. // This emits a single store. @@ -4203,46 +4191,40 @@ transition(atos, vtos); __ verify_oop(R17_tos); - Register Rcurrent_monitor = R11_scratch1, - Rcurrent_obj = R12_scratch2, + Register Rcurrent_monitor = R3_ARG1, + Rcurrent_obj = R4_ARG2, Robj_to_lock = R17_tos, - Rcurrent_obj_addr = R3_ARG1, - Rlimit = R4_ARG2; + Rscratch = R11_scratch1, + Rbot = R12_scratch2; + Label Lfound, Lillegal_monitor_state; - // Check corner case: unbalanced monitorEnter / Exit. - __ ld(Rlimit, 0, R1_SP); - __ addi(Rlimit, Rlimit, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes())); // Monitor base + __ ld(Rscratch, _abi0(callers_sp), R1_SP); // load FP + + // Set up search loop - start with topmost monitor. + __ mr(Rcurrent_monitor, R26_monitor); + __ addi(Rbot, Rscratch, -frame::ijava_state_size); // Null pointer check. - __ null_check_throw(Robj_to_lock, -1, R11_scratch1); + __ null_check_throw(Robj_to_lock, -1, Rscratch); - __ cmpld(CCR0, R26_monitor, Rlimit); - __ bgt(CCR0, Lillegal_monitor_state); + // Check corner case: unbalanced monitorEnter / Exit. + __ cmpld(CCR0, Rcurrent_monitor, Rbot); + __ beq(CCR0, Lillegal_monitor_state); // Find the corresponding slot in the monitors stack section. { Label Lloop; - // Start with topmost monitor. - __ addi(Rcurrent_obj_addr, R26_monitor, in_bytes(BasicObjectLock::obj_offset())); - __ addi(Rlimit, Rlimit, in_bytes(BasicObjectLock::obj_offset())); - __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr); - __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize); - __ bind(Lloop); + __ ld(Rcurrent_obj, in_bytes(BasicObjectLock::obj_offset()), Rcurrent_monitor); // Is this entry for same obj? __ cmpd(CCR0, Rcurrent_obj, Robj_to_lock); __ beq(CCR0, Lfound); - // Check if last allocated BasicLockObj reached. - - __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr); - __ cmpld(CCR0, Rcurrent_obj_addr, Rlimit); - __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize); - - // Next iteration if unchecked BasicObjectLocks exist on the stack. - __ ble(CCR0, Lloop); + __ addi(Rcurrent_monitor, Rcurrent_monitor, frame::interpreter_frame_monitor_size_in_bytes()); + __ cmpld(CCR0, Rcurrent_monitor, Rbot); + __ bne(CCR0, Lloop); } // Fell through without finding the basic obj lock => throw up! @@ -4252,8 +4234,6 @@ __ align(32, 12); __ bind(Lfound); - __ addi(Rcurrent_monitor, Rcurrent_obj_addr, - -(frame::interpreter_frame_monitor_size() * wordSize) - in_bytes(BasicObjectLock::obj_offset())); __ unlock_object(Rcurrent_monitor); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -363,7 +363,7 @@ if (LockingMode == LM_MONITOR) { __ j(*stub->entry()); } else { - __ unlock_object(x15, x14, x10, *stub->entry()); + __ unlock_object(x15, x14, x10, x16, *stub->entry()); } __ bind(*stub->continuation()); } @@ -1506,22 +1506,23 @@ Register obj = op->obj_opr()->as_register(); // may not be an oop Register hdr = op->hdr_opr()->as_register(); Register lock = op->lock_opr()->as_register(); + Register temp = op->scratch_opr()->as_register(); if (LockingMode == LM_MONITOR) { if (op->info() != nullptr) { add_debug_info_for_null_check_here(op->info()); - __ null_check(obj); + __ null_check(obj, -1); } __ j(*op->stub()->entry()); } 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 - int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry()); + int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry()); if (op->info() != nullptr) { add_debug_info_for_null_check(null_check_offset, op->info()); } } else if (op->code() == lir_unlock) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); - __ unlock_object(hdr, obj, lock, *op->stub()->entry()); + __ unlock_object(hdr, obj, lock, temp, *op->stub()->entry()); } else { Unimplemented(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -274,6 +274,7 @@ // "lock" stores the address of the monitor stack slot, so this is not an oop LIR_Opr lock = new_register(T_INT); + LIR_Opr scratch = new_register(T_INT); CodeEmitInfo* info_for_exception = nullptr; if (x->needs_null_check()) { @@ -282,7 +283,7 @@ // this CodeEmitInfo must not have the xhandlers because here the // object is already locked (xhandlers expect object to be unlocked) CodeEmitInfo* info = state_for(x, x->state(), true); - monitor_enter(obj.result(), lock, syncTempOpr(), LIR_OprFact::illegalOpr, + monitor_enter(obj.result(), lock, syncTempOpr(), scratch, x->monitor_no(), info_for_exception, info); } @@ -294,8 +295,9 @@ LIR_Opr lock = new_register(T_INT); LIR_Opr obj_temp = new_register(T_INT); + LIR_Opr scratch = new_register(T_INT); set_no_result(x); - monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no()); + monitor_exit(obj_temp, lock, syncTempOpr(), scratch, x->monitor_no()); } // neg @@ -801,7 +803,7 @@ } void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) { - fatal("vectorizedMismatch intrinsic is not implemented on this platform"); + ShouldNotReachHere(); } // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -49,10 +49,10 @@ } } -int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { +int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) { const int aligned_mask = BytesPerWord - 1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); - assert_different_registers(hdr, obj, disp_hdr); + assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1); int null_check_offset = -1; verify_oop(obj); @@ -65,15 +65,15 @@ if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(hdr, obj); lwu(hdr, Address(hdr, Klass::access_flags_offset())); - test_bit(t0, hdr, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); - bnez(t0, slow_case, true /* is_far */); + test_bit(temp, hdr, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + bnez(temp, slow_case, true /* is_far */); } // Load object header ld(hdr, Address(obj, hdr_offset)); if (LockingMode == LM_LIGHTWEIGHT) { - fast_lock(obj, hdr, t0, t1, slow_case); + lightweight_lock(obj, hdr, temp, t1, slow_case); } else if (LockingMode == LM_LEGACY) { Label done; // and mark it as unlocked @@ -83,8 +83,8 @@ // test if object header is still the same (i.e. unlocked), and if so, store the // displaced header address in the object header - if it is not the same, get the // object header instead - la(t1, Address(obj, hdr_offset)); - cmpxchgptr(hdr, disp_hdr, t1, t0, done, /*fallthough*/nullptr); + la(temp, Address(obj, hdr_offset)); + cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr); // if the object header was the same, we're done // if the object header was not the same, it is now in the hdr register // => test if it is a stack pointer into the same stack (recursive locking), i.e.: @@ -100,8 +100,8 @@ // assuming both the stack pointer and page_size have their least // significant 2 bits cleared and page_size is a power of 2 sub(hdr, hdr, sp); - mv(t0, aligned_mask - (int)os::vm_page_size()); - andr(hdr, hdr, t0); + mv(temp, aligned_mask - (int)os::vm_page_size()); + andr(hdr, hdr, temp); // for recursive locking, the result is zero => save it in the displaced header // location (null in the displaced hdr location indicates recursive locking) sd(hdr, Address(disp_hdr, 0)); @@ -115,10 +115,10 @@ return null_check_offset; } -void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { +void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) { const int aligned_mask = BytesPerWord - 1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); - assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different"); + assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1); Label done; if (LockingMode != LM_LIGHTWEIGHT) { @@ -135,9 +135,9 @@ if (LockingMode == LM_LIGHTWEIGHT) { ld(hdr, Address(obj, oopDesc::mark_offset_in_bytes())); - test_bit(t0, hdr, exact_log2(markWord::monitor_value)); - bnez(t0, slow_case, /* is_far */ true); - fast_unlock(obj, hdr, t0, t1, slow_case); + test_bit(temp, hdr, exact_log2(markWord::monitor_value)); + bnez(temp, slow_case, /* is_far */ true); + lightweight_unlock(obj, hdr, temp, t1, slow_case); } else if (LockingMode == LM_LEGACY) { // test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object - if the object header is not pointing to @@ -145,8 +145,8 @@ // if the object header was not pointing to the displaced header, // we do unlocking via runtime call if (hdr_offset) { - la(t0, Address(obj, hdr_offset)); - cmpxchgptr(disp_hdr, hdr, t0, t1, done, &slow_case); + la(temp, Address(obj, hdr_offset)); + cmpxchgptr(disp_hdr, hdr, temp, t1, done, &slow_case); } else { cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -59,14 +59,16 @@ // hdr : must be x10, contents destroyed // obj : must point to the object to lock, contents preserved // disp_hdr: must point to the displaced header location, contents preserved + // temp : temporary register, must not be scratch register t0 or t1 // returns code offset at which to add null check debug information - int lock_object (Register swap, Register obj, Register disp_hdr, Label& slow_case); + int lock_object(Register swap, Register obj, Register disp_hdr, Register temp, Label& slow_case); // unlocking // hdr : contents destroyed // obj : must point to the object to lock, contents preserved // disp_hdr: must be x10 & must point to the displaced header location, contents destroyed - void unlock_object(Register swap, Register obj, Register lock, Label& slow_case); + // temp : temporary register, must not be scratch register t0 or t1 + void unlock_object(Register swap, Register obj, Register lock, Register temp, Label& slow_case); void initialize_object( Register obj, // result: pointer to object after successful allocation diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -43,6 +43,223 @@ #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") +void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, + Register tmp1Reg, Register tmp2Reg, Register tmp3Reg) { + // Use cr register to indicate the fast_lock result: zero for success; non-zero for failure. + Register flag = t1; + Register oop = objectReg; + Register box = boxReg; + Register disp_hdr = tmp1Reg; + Register tmp = tmp2Reg; + Label cont; + Label object_has_monitor; + Label count, no_count; + + assert_different_registers(oop, box, tmp, disp_hdr, flag, tmp3Reg, t0); + + // Load markWord from object into displaced_header. + ld(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); + + if (DiagnoseSyncOnValueBasedClasses != 0) { + load_klass(flag, oop); + lwu(flag, Address(flag, Klass::access_flags_offset())); + test_bit(flag, flag, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + bnez(flag, cont, true /* is_far */); + } + + // Check for existing monitor + test_bit(t0, disp_hdr, exact_log2(markWord::monitor_value)); + bnez(t0, object_has_monitor); + + if (LockingMode == LM_MONITOR) { + mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow-path + j(cont); + } else if (LockingMode == LM_LEGACY) { + // Set tmp to be (markWord of object | UNLOCK_VALUE). + ori(tmp, disp_hdr, markWord::unlocked_value); + + // Initialize the box. (Must happen before we update the object mark!) + sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); + + // Compare object markWord with an unlocked value (tmp) and if + // equal exchange the stack address of our box with object markWord. + // On failure disp_hdr contains the possibly locked markWord. + cmpxchg(/*memory address*/oop, /*expected value*/tmp, /*new value*/box, Assembler::int64, Assembler::aq, + Assembler::rl, /*result*/disp_hdr); + mv(flag, zr); + beq(disp_hdr, tmp, cont); // prepare zero flag and goto cont if we won the cas + + assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + + // If the compare-and-exchange succeeded, then we found an unlocked + // object, will have now locked it will continue at label cont + // We did not see an unlocked object so try the fast recursive case. + + // Check if the owner is self by comparing the value in the + // markWord of object (disp_hdr) with the stack pointer. + sub(disp_hdr, disp_hdr, sp); + mv(tmp, (intptr_t) (~(os::vm_page_size()-1) | (uintptr_t)markWord::lock_mask_in_place)); + // If (mark & lock_mask) == 0 and mark - sp < page_size, we are stack-locking and goto cont, + // hence we can store 0 as the displaced header in the box, which indicates that it is a + // recursive lock. + andr(tmp/*==0?*/, disp_hdr, tmp); + sd(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); + mv(flag, tmp); // we can use the value of tmp as the result here + j(cont); + } else { + assert(LockingMode == LM_LIGHTWEIGHT, ""); + Label slow; + lightweight_lock(oop, disp_hdr, tmp, tmp3Reg, slow); + + // Indicate success on completion. + mv(flag, zr); + j(count); + bind(slow); + mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow-path + j(no_count); + } + + // Handle existing monitor. + bind(object_has_monitor); + // The object's monitor m is unlocked iff m->owner == NULL, + // otherwise m->owner may contain a thread or a stack address. + // + // Try to CAS m->owner from NULL to current thread. + add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset()) - markWord::monitor_value)); + cmpxchg(/*memory address*/tmp, /*expected value*/zr, /*new value*/xthread, Assembler::int64, Assembler::aq, + Assembler::rl, /*result*/flag); // cas succeeds if flag == zr(expected) + + if (LockingMode != LM_LIGHTWEIGHT) { + // Store a non-null value into the box to avoid looking like a re-entrant + // lock. The fast-path monitor unlock code checks for + // markWord::monitor_value so use markWord::unused_mark which has the + // relevant bit set, and also matches ObjectSynchronizer::slow_enter. + mv(tmp, (address)markWord::unused_mark().value()); + sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); + } + + beqz(flag, cont); // CAS success means locking succeeded + + bne(flag, xthread, cont); // Check for recursive locking + + // Recursive lock case + mv(flag, zr); + increment(Address(disp_hdr, in_bytes(ObjectMonitor::recursions_offset()) - markWord::monitor_value), 1, t0, tmp); + + bind(cont); + // zero flag indicates success + // non-zero flag indicates failure + bnez(flag, no_count); + + bind(count); + increment(Address(xthread, JavaThread::held_monitor_count_offset()), 1, t0, tmp); + + bind(no_count); +} + +void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, + Register tmp1Reg, Register tmp2Reg) { + // Use cr register to indicate the fast_unlock result: zero for success; non-zero for failure. + Register flag = t1; + Register oop = objectReg; + Register box = boxReg; + Register disp_hdr = tmp1Reg; + Register tmp = tmp2Reg; + Label cont; + Label object_has_monitor; + Label count, no_count; + + assert_different_registers(oop, box, tmp, disp_hdr, flag, t0); + + if (LockingMode == LM_LEGACY) { + // Find the lock address and load the displaced header from the stack. + ld(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); + + // If the displaced header is 0, we have a recursive unlock. + mv(flag, disp_hdr); + beqz(disp_hdr, cont); + } + + // Handle existing monitor. + ld(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); + test_bit(t0, tmp, exact_log2(markWord::monitor_value)); + bnez(t0, object_has_monitor); + + if (LockingMode == LM_MONITOR) { + mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow path + j(cont); + } else if (LockingMode == LM_LEGACY) { + // Check if it is still a light weight lock, this is true if we + // see the stack address of the basicLock in the markWord of the + // object. + + cmpxchg(/*memory address*/oop, /*expected value*/box, /*new value*/disp_hdr, Assembler::int64, Assembler::relaxed, + Assembler::rl, /*result*/tmp); + xorr(flag, box, tmp); // box == tmp if cas succeeds + j(cont); + } else { + assert(LockingMode == LM_LIGHTWEIGHT, ""); + Label slow; + lightweight_unlock(oop, tmp, box, disp_hdr, slow); + + // Indicate success on completion. + mv(flag, zr); + j(count); + bind(slow); + mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow path + j(no_count); + } + + assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + + // Handle existing monitor. + bind(object_has_monitor); + STATIC_ASSERT(markWord::monitor_value <= INT_MAX); + add(tmp, tmp, -(int)markWord::monitor_value); // monitor + + if (LockingMode == LM_LIGHTWEIGHT) { + // If the owner is anonymous, we need to fix it -- in an outline stub. + Register tmp2 = disp_hdr; + ld(tmp2, Address(tmp, ObjectMonitor::owner_offset())); + test_bit(t0, tmp2, exact_log2(ObjectMonitor::ANONYMOUS_OWNER)); + C2HandleAnonOMOwnerStub* stub = new (Compile::current()->comp_arena()) C2HandleAnonOMOwnerStub(tmp, tmp2); + Compile::current()->output()->add_stub(stub); + bnez(t0, stub->entry(), /* is_far */ true); + bind(stub->continuation()); + } + + ld(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); + + Label notRecursive; + beqz(disp_hdr, notRecursive); // Will be 0 if not recursive. + + // Recursive lock + addi(disp_hdr, disp_hdr, -1); + sd(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); + mv(flag, zr); + j(cont); + + bind(notRecursive); + ld(flag, Address(tmp, ObjectMonitor::EntryList_offset())); + ld(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset())); + orr(flag, flag, disp_hdr); // Will be 0 if both are 0. + bnez(flag, cont); + // need a release store here + la(tmp, Address(tmp, ObjectMonitor::owner_offset())); + membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); + sd(zr, Address(tmp)); // set unowned + + bind(cont); + // zero flag indicates success + // non-zero flag indicates failure + bnez(flag, no_count); + + bind(count); + decrement(Address(xthread, JavaThread::held_monitor_count_offset()), 1, t0, tmp); + + bind(no_count); +} + // short string // StringUTF16.indexOfChar // StringLatin1.indexOfChar @@ -1898,13 +2115,13 @@ } } } else if (src_bt == T_INT) { - // T_SHORT - vsetvli(t0, t0, Assembler::e16, Assembler::mf2); - vncvt_x_x_w(dst, src); - if (dst_bt == T_BYTE) { - vsetvli(t0, t0, Assembler::e8, Assembler::mf2); - vncvt_x_x_w(dst, dst); - } + // T_SHORT + vsetvli(t0, t0, Assembler::e16, Assembler::mf2); + vncvt_x_x_w(dst, src); + if (dst_bt == T_BYTE) { + vsetvli(t0, t0, Assembler::e8, Assembler::mf2); + vncvt_x_x_w(dst, dst); + } } else if (src_bt == T_SHORT) { vsetvli(t0, t0, Assembler::e8, Assembler::mf2); vncvt_x_x_w(dst, src); @@ -1920,8 +2137,6 @@ } VFCVT_SAFE(vfcvt_rtz_x_f_v); -VFCVT_SAFE(vfwcvt_rtz_x_f_v); -VFCVT_SAFE(vfncvt_rtz_x_f_w); #undef VFCVT_SAFE diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -39,6 +39,11 @@ VectorRegister vrs, bool is_latin, Label& DONE); public: + // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file. + // See full description in macroAssembler_riscv.cpp. + void fast_lock(Register object, Register box, Register tmp1, Register tmp2, Register tmp3); + void fast_unlock(Register object, Register box, Register tmp1, Register tmp2); + void string_compare(Register str1, Register str2, Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2, Register tmp3, @@ -242,8 +247,6 @@ VectorRegister src, BasicType src_bt); void vfcvt_rtz_x_f_v_safe(VectorRegister dst, VectorRegister src); - void vfwcvt_rtz_x_f_v_safe(VectorRegister dst, VectorRegister src); - void vfncvt_rtz_x_f_w_safe(VectorRegister dst, VectorRegister src); void extract_v(Register dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp); void extract_fp_v(FloatRegister dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv.ad 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv.ad 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,285 @@ +// +// Copyright (c) 2018, Red Hat, Inc. All rights reserved. +// Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// +// + +source_hpp %{ +#include "gc/shenandoah/shenandoahBarrierSet.hpp" +#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" +%} + +instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapP_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapN_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_reserved(n)); + match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapPAcq_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::aq /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_reserved(n)); + match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapNAcq_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::aq /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + effect(TEMP_DEF res, TEMP tmp, KILL cr); + + format %{ + "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, + true /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP_DEF res, TEMP tmp, KILL cr); + format %{ + "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndExchangeP_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, + true /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapN_shenandoah" + "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_reserved(n)); + match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP_DEF res, TEMP tmp, KILL cr); + format %{ + "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::aq /* acquire */, Assembler::rl /* release */, + true /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_reserved(n)); + match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP_DEF res, TEMP tmp, KILL cr); + format %{ + "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::aq /* acquire */, Assembler::rl /* release */, + true /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapP_shenandoah" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_reserved(n)); + match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapNAcq_shenandoah" + "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::aq /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_reserved(n)); + match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); + ins_cost(10 * DEFAULT_COST); + + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapPAcq_shenandoah" + "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mv(tmp, $oldval$$Register); // Must not clobber oldval. + // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + Assembler::aq /* acquire */, Assembler::rl /* release */, + false /* is_cae */, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv64.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv64.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv64.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/shenandoah/shenandoah_riscv64.ad 1970-01-01 00:00:00.000000000 +0000 @@ -1,285 +0,0 @@ -// -// Copyright (c) 2018, Red Hat, Inc. All rights reserved. -// Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -source_hpp %{ -#include "gc/shenandoah/shenandoahBarrierSet.hpp" -#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" -%} - -instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ - match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - - format %{ - "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapP_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ - match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - - format %{ - "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapN_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); - match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - - format %{ - "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapPAcq_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::aq /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); - match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - - format %{ - "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapNAcq_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::aq /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ - match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - effect(TEMP_DEF res, TEMP tmp, KILL cr); - - format %{ - "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, - true /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ - match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP_DEF res, TEMP tmp, KILL cr); - format %{ - "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndExchangeP_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, - true /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ - match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - format %{ - "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapN_shenandoah" - "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); - match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP_DEF res, TEMP tmp, KILL cr); - format %{ - "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::aq /* acquire */, Assembler::rl /* release */, - true /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); - match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP_DEF res, TEMP tmp, KILL cr); - format %{ - "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::aq /* acquire */, Assembler::rl /* release */, - true /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ - match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - format %{ - "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapP_shenandoah" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); - match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - format %{ - "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapNAcq_shenandoah" - "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::aq /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); - match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); - ins_cost(10 * DEFAULT_COST); - - effect(TEMP tmp, KILL cr); - format %{ - "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapPAcq_shenandoah" - "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" - %} - - ins_encode %{ - Register tmp = $tmp$$Register; - __ mv(tmp, $oldval$$Register); // Must not clobber oldval. - // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop - ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, - Assembler::aq /* acquire */, Assembler::rl /* release */, - false /* is_cae */, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/x/x_riscv.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/x/x_riscv.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/x/x_riscv.ad 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/x/x_riscv.ad 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,233 @@ +// +// Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// + +source_hpp %{ + +#include "gc/shared/gc_globals.hpp" +#include "gc/x/c2/xBarrierSetC2.hpp" +#include "gc/x/xThreadLocalData.hpp" + +%} + +source %{ + +static void x_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, int barrier_data) { + if (barrier_data == XLoadBarrierElided) { + return; + } + XLoadBarrierStubC2* const stub = XLoadBarrierStubC2::create(node, ref_addr, ref, tmp, barrier_data); + __ ld(tmp, Address(xthread, XThreadLocalData::address_bad_mask_offset())); + __ andr(tmp, tmp, ref); + __ bnez(tmp, *stub->entry(), true /* far */); + __ bind(*stub->continuation()); +} + +static void x_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) { + XLoadBarrierStubC2* const stub = XLoadBarrierStubC2::create(node, ref_addr, ref, tmp, XLoadBarrierStrong); + __ j(*stub->entry()); + __ bind(*stub->continuation()); +} + +%} + +// Load Pointer +instruct xLoadP(iRegPNoSp dst, memory mem) +%{ + match(Set dst (LoadP mem)); + predicate(UseZGC && !ZGenerational && (n->as_Load()->barrier_data() != 0)); + effect(TEMP dst); + + ins_cost(4 * DEFAULT_COST); + + format %{ "ld $dst, $mem, #@zLoadP" %} + + ins_encode %{ + const Address ref_addr (as_Register($mem$$base), $mem$$disp); + __ ld($dst$$Register, ref_addr); + x_load_barrier(_masm, this, ref_addr, $dst$$Register, t0 /* tmp */, barrier_data()); + %} + + ins_pipe(iload_reg_mem); +%} + +instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ + match(Set res (CompareAndSwapP mem (Binary oldval newval))); + match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); + predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong); + effect(KILL cr, TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapP\n\t" + "mv $res, $res == $oldval" %} + + ins_encode %{ + Label failed; + guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result_as_bool */); + __ beqz($res$$Register, failed); + __ mv(t0, $oldval$$Register); + __ bind(failed); + if (barrier_data() != XLoadBarrierElided) { + Label good; + __ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */); + __ andr(t1, t1, t0); + __ beqz(t1, good); + x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result_as_bool */); + __ bind(good); + } + %} + + ins_pipe(pipe_slow); +%} + +instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ + match(Set res (CompareAndSwapP mem (Binary oldval newval))); + match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); + predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == XLoadBarrierStrong)); + effect(KILL cr, TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapPAcq\n\t" + "mv $res, $res == $oldval" %} + + ins_encode %{ + Label failed; + guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result_as_bool */); + __ beqz($res$$Register, failed); + __ mv(t0, $oldval$$Register); + __ bind(failed); + if (barrier_data() != XLoadBarrierElided) { + Label good; + __ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */); + __ andr(t1, t1, t0); + __ beqz(t1, good); + x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result_as_bool */); + __ bind(good); + } + %} + + ins_pipe(pipe_slow); +%} + +instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{ + match(Set res (CompareAndExchangeP mem (Binary oldval newval))); + predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong); + effect(TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangeP" %} + + ins_encode %{ + guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register); + if (barrier_data() != XLoadBarrierElided) { + Label good; + __ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset())); + __ andr(t0, t0, $res$$Register); + __ beqz(t0, good); + x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register); + __ bind(good); + } + %} + + ins_pipe(pipe_slow); +%} + +instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{ + match(Set res (CompareAndExchangeP mem (Binary oldval newval))); + predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong); + effect(TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangePAcq" %} + + ins_encode %{ + guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register); + if (barrier_data() != XLoadBarrierElided) { + Label good; + __ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset())); + __ andr(t0, t0, $res$$Register); + __ beqz(t0, good); + x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */); + __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, + Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register); + __ bind(good); + } + %} + + ins_pipe(pipe_slow); +%} + +instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ + match(Set prev (GetAndSetP mem newv)); + predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); + effect(TEMP_DEF prev, KILL cr); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "atomic_xchg $prev, $newv, [$mem], #@zGetAndSetP" %} + + ins_encode %{ + __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); + x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data()); + %} + + ins_pipe(pipe_serial); +%} + +instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ + match(Set prev (GetAndSetP mem newv)); + predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() != 0)); + effect(TEMP_DEF prev, KILL cr); + + ins_cost(VOLATILE_REF_COST); + + format %{ "atomic_xchg_acq $prev, $newv, [$mem], #@zGetAndSetPAcq" %} + + ins_encode %{ + __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); + x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data()); + %} + ins_pipe(pipe_serial); +%} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/x/x_riscv64.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/x/x_riscv64.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/x/x_riscv64.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/x/x_riscv64.ad 1970-01-01 00:00:00.000000000 +0000 @@ -1,233 +0,0 @@ -// -// Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// - -source_hpp %{ - -#include "gc/shared/gc_globals.hpp" -#include "gc/x/c2/xBarrierSetC2.hpp" -#include "gc/x/xThreadLocalData.hpp" - -%} - -source %{ - -static void x_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, int barrier_data) { - if (barrier_data == XLoadBarrierElided) { - return; - } - XLoadBarrierStubC2* const stub = XLoadBarrierStubC2::create(node, ref_addr, ref, tmp, barrier_data); - __ ld(tmp, Address(xthread, XThreadLocalData::address_bad_mask_offset())); - __ andr(tmp, tmp, ref); - __ bnez(tmp, *stub->entry(), true /* far */); - __ bind(*stub->continuation()); -} - -static void x_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) { - XLoadBarrierStubC2* const stub = XLoadBarrierStubC2::create(node, ref_addr, ref, tmp, XLoadBarrierStrong); - __ j(*stub->entry()); - __ bind(*stub->continuation()); -} - -%} - -// Load Pointer -instruct xLoadP(iRegPNoSp dst, memory mem) -%{ - match(Set dst (LoadP mem)); - predicate(UseZGC && !ZGenerational && (n->as_Load()->barrier_data() != 0)); - effect(TEMP dst); - - ins_cost(4 * DEFAULT_COST); - - format %{ "ld $dst, $mem, #@zLoadP" %} - - ins_encode %{ - const Address ref_addr (as_Register($mem$$base), $mem$$disp); - __ ld($dst$$Register, ref_addr); - x_load_barrier(_masm, this, ref_addr, $dst$$Register, t0 /* tmp */, barrier_data()); - %} - - ins_pipe(iload_reg_mem); -%} - -instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ - match(Set res (CompareAndSwapP mem (Binary oldval newval))); - match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); - predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong); - effect(KILL cr, TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapP\n\t" - "mv $res, $res == $oldval" %} - - ins_encode %{ - Label failed; - guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, - true /* result_as_bool */); - __ beqz($res$$Register, failed); - __ mv(t0, $oldval$$Register); - __ bind(failed); - if (barrier_data() != XLoadBarrierElided) { - Label good; - __ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */); - __ andr(t1, t1, t0); - __ beqz(t1, good); - x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, - true /* result_as_bool */); - __ bind(good); - } - %} - - ins_pipe(pipe_slow); -%} - -instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ - match(Set res (CompareAndSwapP mem (Binary oldval newval))); - match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); - predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == XLoadBarrierStrong)); - effect(KILL cr, TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapPAcq\n\t" - "mv $res, $res == $oldval" %} - - ins_encode %{ - Label failed; - guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, - true /* result_as_bool */); - __ beqz($res$$Register, failed); - __ mv(t0, $oldval$$Register); - __ bind(failed); - if (barrier_data() != XLoadBarrierElided) { - Label good; - __ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */); - __ andr(t1, t1, t0); - __ beqz(t1, good); - x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, - true /* result_as_bool */); - __ bind(good); - } - %} - - ins_pipe(pipe_slow); -%} - -instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{ - match(Set res (CompareAndExchangeP mem (Binary oldval newval))); - predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong); - effect(TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangeP" %} - - ins_encode %{ - guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register); - if (barrier_data() != XLoadBarrierElided) { - Label good; - __ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset())); - __ andr(t0, t0, $res$$Register); - __ beqz(t0, good); - x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register); - __ bind(good); - } - %} - - ins_pipe(pipe_slow); -%} - -instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{ - match(Set res (CompareAndExchangeP mem (Binary oldval newval))); - predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong); - effect(TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangePAcq" %} - - ins_encode %{ - guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register); - if (barrier_data() != XLoadBarrierElided) { - Label good; - __ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset())); - __ andr(t0, t0, $res$$Register); - __ beqz(t0, good); - x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */); - __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64, - Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register); - __ bind(good); - } - %} - - ins_pipe(pipe_slow); -%} - -instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ - match(Set prev (GetAndSetP mem newv)); - predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); - effect(TEMP_DEF prev, KILL cr); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "atomic_xchg $prev, $newv, [$mem], #@zGetAndSetP" %} - - ins_encode %{ - __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); - x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data()); - %} - - ins_pipe(pipe_serial); -%} - -instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ - match(Set prev (GetAndSetP mem newv)); - predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() != 0)); - effect(TEMP_DEF prev, KILL cr); - - ins_cost(VOLATILE_REF_COST); - - format %{ "atomic_xchg_acq $prev, $newv, [$mem], #@zGetAndSetPAcq" %} - - ins_encode %{ - __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); - x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data()); - %} - ins_pipe(pipe_serial); -%} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/z/z_riscv.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/z/z_riscv.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/z/z_riscv.ad 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/z/z_riscv.ad 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,248 @@ +// +// Copyright (c) 2019, 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. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// + +source_hpp %{ + +#include "gc/shared/gc_globals.hpp" +#include "gc/z/c2/zBarrierSetC2.hpp" +#include "gc/z/zThreadLocalData.hpp" + +%} + +source %{ +#include "gc/z/zBarrierSetAssembler.hpp" + +static void z_color(MacroAssembler& _masm, const MachNode* node, Register dst, Register src, Register tmp) { + assert_different_registers(dst, tmp); + + __ relocate(barrier_Relocation::spec(), [&] { + __ li16u(tmp, barrier_Relocation::unpatched); + }, ZBarrierRelocationFormatStoreGoodBits); + __ slli(dst, src, ZPointerLoadShift); + __ orr(dst, dst, tmp); +} + +static void z_uncolor(MacroAssembler& _masm, const MachNode* node, Register ref) { + __ srli(ref, ref, ZPointerLoadShift); +} + +static void check_color(MacroAssembler& _masm, Register ref, bool on_non_strong, Register result) { + int format = on_non_strong ? ZBarrierRelocationFormatMarkBadMask + : ZBarrierRelocationFormatLoadBadMask; + __ relocate(barrier_Relocation::spec(), [&] { + __ li16u(result, barrier_Relocation::unpatched); + }, format); + __ andr(result, ref, result); +} + +static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) { + const bool on_non_strong = + ((node->barrier_data() & ZBarrierWeak) != 0) || + ((node->barrier_data() & ZBarrierPhantom) != 0); + + if (node->barrier_data() == ZBarrierElided) { + z_uncolor(_masm, node, ref); + return; + } + + ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref); + Label good; + check_color(_masm, ref, on_non_strong, tmp); + __ beqz(tmp, good); + __ j(*stub->entry()); + + __ bind(good); + z_uncolor(_masm, node, ref); + __ bind(*stub->continuation()); +} + +static void z_store_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register rnew_zaddress, Register rnew_zpointer, Register tmp, bool is_atomic) { + if (node->barrier_data() == ZBarrierElided) { + z_color(_masm, node, rnew_zpointer, rnew_zaddress, t0); + } else { + bool is_native = (node->barrier_data() & ZBarrierNative) != 0; + ZStoreBarrierStubC2* const stub = ZStoreBarrierStubC2::create(node, ref_addr, rnew_zaddress, rnew_zpointer, is_native, is_atomic); + ZBarrierSetAssembler* bs_asm = ZBarrierSet::assembler(); + bs_asm->store_barrier_fast(&_masm, ref_addr, rnew_zaddress, rnew_zpointer, tmp, true /* in_nmethod */, is_atomic, *stub->entry(), *stub->continuation()); + } +} +%} + +// Load Pointer +instruct zLoadP(iRegPNoSp dst, memory mem) +%{ + match(Set dst (LoadP mem)); + predicate(UseZGC && ZGenerational && n->as_Load()->barrier_data() != 0); + effect(TEMP dst); + + ins_cost(4 * DEFAULT_COST); + + format %{ "ld $dst, $mem, #@zLoadP" %} + + ins_encode %{ + const Address ref_addr(as_Register($mem$$base), $mem$$disp); + __ ld($dst$$Register, ref_addr); + z_load_barrier(_masm, this, ref_addr, $dst$$Register, t0); + %} + + ins_pipe(iload_reg_mem); +%} + +// Store Pointer +instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr) +%{ + predicate(UseZGC && ZGenerational && n->as_Store()->barrier_data() != 0); + match(Set mem (StoreP mem src)); + effect(TEMP tmp, KILL cr); + + ins_cost(125); // XXX + format %{ "sd $mem, $src\t# ptr" %} + ins_encode %{ + const Address ref_addr(as_Register($mem$$base), $mem$$disp); + z_store_barrier(_masm, this, ref_addr, $src$$Register, $tmp$$Register, t1, false /* is_atomic */); + __ sd($tmp$$Register, ref_addr); + %} + ins_pipe(pipe_serial); +%} + +instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ + match(Set res (CompareAndSwapP mem (Binary oldval newval))); + match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); + predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); + effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapP\n\t" + "mv $res, $res == $oldval" %} + + ins_encode %{ + guarantee($mem$$disp == 0, "impossible encoding"); + Address ref_addr($mem$$Register); + z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); + z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); + __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */); + %} + + ins_pipe(pipe_slow); +%} + +instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ + match(Set res (CompareAndSwapP mem (Binary oldval newval))); + match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); + predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); + effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapPAcq\n\t" + "mv $res, $res == $oldval" %} + + ins_encode %{ + guarantee($mem$$disp == 0, "impossible encoding"); + Address ref_addr($mem$$Register); + z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); + z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); + __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */); + %} + + ins_pipe(pipe_slow); +%} + +instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ + match(Set res (CompareAndExchangeP mem (Binary oldval newval))); + predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); + effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangeP" %} + + ins_encode %{ + guarantee($mem$$disp == 0, "impossible encoding"); + Address ref_addr($mem$$Register); + z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); + z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); + __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register); + z_uncolor(_masm, this, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ + match(Set res (CompareAndExchangeP mem (Binary oldval newval))); + predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); + effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangePAcq" %} + + ins_encode %{ + guarantee($mem$$disp == 0, "impossible encoding"); + Address ref_addr($mem$$Register); + z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); + z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); + __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register); + z_uncolor(_masm, this, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ + match(Set prev (GetAndSetP mem newv)); + predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); + effect(TEMP_DEF prev, KILL cr); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "atomic_xchg $prev, $newv, [$mem], #@zGetAndSetP" %} + + ins_encode %{ + z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */); + __ atomic_xchg($prev$$Register, $prev$$Register, $mem$$Register); + z_uncolor(_masm, this, $prev$$Register); + %} + + ins_pipe(pipe_serial); +%} + +instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ + match(Set prev (GetAndSetP mem newv)); + predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); + effect(TEMP_DEF prev, KILL cr); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ "atomic_xchg_acq $prev, $newv, [$mem], #@zGetAndSetPAcq" %} + + ins_encode %{ + z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */); + __ atomic_xchgal($prev$$Register, $prev$$Register, $mem$$Register); + z_uncolor(_masm, this, $prev$$Register); + %} + ins_pipe(pipe_serial); +%} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/z/z_riscv64.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/z/z_riscv64.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/gc/z/z_riscv64.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/gc/z/z_riscv64.ad 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -// -// Copyright (c) 2019, 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. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// - -source_hpp %{ - -#include "gc/shared/gc_globals.hpp" -#include "gc/z/c2/zBarrierSetC2.hpp" -#include "gc/z/zThreadLocalData.hpp" - -%} - -source %{ -#include "gc/z/zBarrierSetAssembler.hpp" - -static void z_color(MacroAssembler& _masm, const MachNode* node, Register dst, Register src, Register tmp) { - assert_different_registers(dst, tmp); - - __ relocate(barrier_Relocation::spec(), [&] { - __ li16u(tmp, barrier_Relocation::unpatched); - }, ZBarrierRelocationFormatStoreGoodBits); - __ slli(dst, src, ZPointerLoadShift); - __ orr(dst, dst, tmp); -} - -static void z_uncolor(MacroAssembler& _masm, const MachNode* node, Register ref) { - __ srli(ref, ref, ZPointerLoadShift); -} - -static void check_color(MacroAssembler& _masm, Register ref, bool on_non_strong, Register result) { - int format = on_non_strong ? ZBarrierRelocationFormatMarkBadMask - : ZBarrierRelocationFormatLoadBadMask; - __ relocate(barrier_Relocation::spec(), [&] { - __ li16u(result, barrier_Relocation::unpatched); - }, format); - __ andr(result, ref, result); -} - -static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) { - const bool on_non_strong = - ((node->barrier_data() & ZBarrierWeak) != 0) || - ((node->barrier_data() & ZBarrierPhantom) != 0); - - if (node->barrier_data() == ZBarrierElided) { - z_uncolor(_masm, node, ref); - return; - } - - ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref); - Label good; - check_color(_masm, ref, on_non_strong, tmp); - __ beqz(tmp, good); - __ j(*stub->entry()); - - __ bind(good); - z_uncolor(_masm, node, ref); - __ bind(*stub->continuation()); -} - -static void z_store_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register rnew_zaddress, Register rnew_zpointer, Register tmp, bool is_atomic) { - if (node->barrier_data() == ZBarrierElided) { - z_color(_masm, node, rnew_zpointer, rnew_zaddress, t0); - } else { - bool is_native = (node->barrier_data() & ZBarrierNative) != 0; - ZStoreBarrierStubC2* const stub = ZStoreBarrierStubC2::create(node, ref_addr, rnew_zaddress, rnew_zpointer, is_native, is_atomic); - ZBarrierSetAssembler* bs_asm = ZBarrierSet::assembler(); - bs_asm->store_barrier_fast(&_masm, ref_addr, rnew_zaddress, rnew_zpointer, tmp, true /* in_nmethod */, is_atomic, *stub->entry(), *stub->continuation()); - } -} -%} - -// Load Pointer -instruct zLoadP(iRegPNoSp dst, memory mem) -%{ - match(Set dst (LoadP mem)); - predicate(UseZGC && ZGenerational && n->as_Load()->barrier_data() != 0); - effect(TEMP dst); - - ins_cost(4 * DEFAULT_COST); - - format %{ "ld $dst, $mem, #@zLoadP" %} - - ins_encode %{ - const Address ref_addr(as_Register($mem$$base), $mem$$disp); - __ ld($dst$$Register, ref_addr); - z_load_barrier(_masm, this, ref_addr, $dst$$Register, t0); - %} - - ins_pipe(iload_reg_mem); -%} - -// Store Pointer -instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr) -%{ - predicate(UseZGC && ZGenerational && n->as_Store()->barrier_data() != 0); - match(Set mem (StoreP mem src)); - effect(TEMP tmp, KILL cr); - - ins_cost(125); // XXX - format %{ "sd $mem, $src\t# ptr" %} - ins_encode %{ - const Address ref_addr(as_Register($mem$$base), $mem$$disp); - z_store_barrier(_masm, this, ref_addr, $src$$Register, $tmp$$Register, t1, false /* is_atomic */); - __ sd($tmp$$Register, ref_addr); - %} - ins_pipe(pipe_serial); -%} - -instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ - match(Set res (CompareAndSwapP mem (Binary oldval newval))); - match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); - predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); - effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapP\n\t" - "mv $res, $res == $oldval" %} - - ins_encode %{ - guarantee($mem$$disp == 0, "impossible encoding"); - Address ref_addr($mem$$Register); - z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); - z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); - __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */); - %} - - ins_pipe(pipe_slow); -%} - -instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ - match(Set res (CompareAndSwapP mem (Binary oldval newval))); - match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); - predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); - effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $mem, $oldval, $newval, #@zCompareAndSwapPAcq\n\t" - "mv $res, $res == $oldval" %} - - ins_encode %{ - guarantee($mem$$disp == 0, "impossible encoding"); - Address ref_addr($mem$$Register); - z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); - z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); - __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */); - %} - - ins_pipe(pipe_slow); -%} - -instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ - match(Set res (CompareAndExchangeP mem (Binary oldval newval))); - predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); - effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangeP" %} - - ins_encode %{ - guarantee($mem$$disp == 0, "impossible encoding"); - Address ref_addr($mem$$Register); - z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); - z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); - __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register); - z_uncolor(_masm, this, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{ - match(Set res (CompareAndExchangeP mem (Binary oldval newval))); - predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); - effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "cmpxchg $res = $mem, $oldval, $newval, #@zCompareAndExchangePAcq" %} - - ins_encode %{ - guarantee($mem$$disp == 0, "impossible encoding"); - Address ref_addr($mem$$Register); - z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0); - z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */); - __ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register); - z_uncolor(_masm, this, $res$$Register); - %} - - ins_pipe(pipe_slow); -%} - -instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ - match(Set prev (GetAndSetP mem newv)); - predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); - effect(TEMP_DEF prev, KILL cr); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "atomic_xchg $prev, $newv, [$mem], #@zGetAndSetP" %} - - ins_encode %{ - z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */); - __ atomic_xchg($prev$$Register, $prev$$Register, $mem$$Register); - z_uncolor(_masm, this, $prev$$Register); - %} - - ins_pipe(pipe_serial); -%} - -instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{ - match(Set prev (GetAndSetP mem newv)); - predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0); - effect(TEMP_DEF prev, KILL cr); - - ins_cost(2 * VOLATILE_REF_COST); - - format %{ "atomic_xchg_acq $prev, $newv, [$mem], #@zGetAndSetPAcq" %} - - ins_encode %{ - z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */); - __ atomic_xchgal($prev$$Register, $prev$$Register, $mem$$Register); - z_uncolor(_masm, this, $prev$$Register); - %} - ins_pipe(pipe_serial); -%} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/interp_masm_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/interp_masm_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/interp_masm_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/interp_masm_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -690,7 +690,7 @@ // Check that all monitors are unlocked { Label loop, exception, entry, restart; - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); const Address monitor_block_top( fp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( @@ -763,6 +763,12 @@ // testing if reserved zone needs to be re-enabled Label no_reserved_zone_enabling; + // check if already enabled - if so no re-enabling needed + assert(sizeof(StackOverflow::StackGuardState) == 4, "unexpected size"); + lw(t0, Address(xthread, JavaThread::stack_guard_state_offset())); + subw(t0, t0, StackOverflow::stack_guard_enabled); + beqz(t0, no_reserved_zone_enabling); + ld(t0, Address(xthread, JavaThread::reserved_stack_activation_offset())); ble(t1, t0, no_reserved_zone_enabling); @@ -794,7 +800,7 @@ // // Kills: // x10 -// c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs) +// c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, c_rarg5, .. (param regs) // t0, t1 (temp regs) void InterpreterMacroAssembler::lock_object(Register lock_reg) { @@ -809,6 +815,8 @@ const Register swap_reg = x10; const Register tmp = c_rarg2; const Register obj_reg = c_rarg3; // Will contain the oop + const Register tmp2 = c_rarg4; + const Register tmp3 = c_rarg5; const int obj_offset = in_bytes(BasicObjectLock::obj_offset()); const int lock_offset = in_bytes(BasicObjectLock::lock_offset()); @@ -829,7 +837,7 @@ if (LockingMode == LM_LIGHTWEIGHT) { ld(tmp, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - fast_lock(obj_reg, tmp, t0, t1, slow_case); + lightweight_lock(obj_reg, tmp, tmp2, tmp3, slow_case); j(count); } else if (LockingMode == LM_LEGACY) { // Load (object->mark() | 1) into swap_reg @@ -893,7 +901,7 @@ // // Kills: // x10 -// c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs) +// c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, ... (param regs) // t0, t1 (temp regs) void InterpreterMacroAssembler::unlock_object(Register lock_reg) { @@ -907,6 +915,7 @@ const Register swap_reg = x10; const Register header_reg = c_rarg2; // Will contain the old oopMark const Register obj_reg = c_rarg3; // Will contain the oop + const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock save_bcp(); // Save in case of exception @@ -942,7 +951,7 @@ ld(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); test_bit(t0, header_reg, exact_log2(markWord::monitor_value)); bnez(t0, slow_case); - fast_unlock(obj_reg, header_reg, swap_reg, t0, slow_case); + lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case); j(count); bind(slow_case); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1655,6 +1655,28 @@ sign_extend(Rd, Rd, 32); } +// Rd = Rs1 & (~Rd2) +void MacroAssembler::andn(Register Rd, Register Rs1, Register Rs2) { + if (UseZbb) { + Assembler::andn(Rd, Rs1, Rs2); + return; + } + + notr(Rd, Rs2); + andr(Rd, Rs1, Rd); +} + +// Rd = Rs1 | (~Rd2) +void MacroAssembler::orn(Register Rd, Register Rs1, Register Rs2) { + if (UseZbb) { + Assembler::orn(Rd, Rs1, Rs2); + return; + } + + notr(Rd, Rs2); + orr(Rd, Rs1, Rd); +} + // Note: load_unsigned_short used to be called load_unsigned_word. int MacroAssembler::load_unsigned_short(Register dst, Address src) { int off = offset(); @@ -1969,6 +1991,22 @@ orr(dst, dst, tmp); } +// rotate left with shift bits, 32-bit version +void MacroAssembler::rolw_imm(Register dst, Register src, uint32_t shift, Register tmp) { + if (UseZbb) { + // no roliw available + roriw(dst, src, 32 - shift); + return; + } + + assert_different_registers(dst, tmp); + assert_different_registers(src, tmp); + assert(shift < 32, "shift amount must be < 32"); + srliw(tmp, src, 32 - shift); + slliw(dst, src, shift); + orr(dst, dst, tmp); +} + void MacroAssembler::andi(Register Rd, Register Rn, int64_t imm, Register tmp) { if (is_simm12(imm)) { and_imm12(Rd, Rn, imm); @@ -4598,25 +4636,31 @@ } } -void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos, Register tmp) { +void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos) { assert(bit_pos < 64, "invalid bit range"); if (UseZbs) { bexti(Rd, Rs, bit_pos); return; } - andi(Rd, Rs, 1UL << bit_pos, tmp); + int64_t imm = (int64_t)(1UL << bit_pos); + if (is_simm12(imm)) { + and_imm12(Rd, Rs, imm); + } else { + srli(Rd, Rs, bit_pos); + and_imm12(Rd, Rd, 1); + } } -// Implements fast-locking. +// Implements lightweight-locking. // Branches to slow upon failure to lock the object. // Falls through upon success. // // - obj: the object to be locked // - hdr: the header, already loaded from obj, will be destroyed // - tmp1, tmp2: temporary registers, will be destroyed -void MacroAssembler::fast_lock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) { +void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); - assert_different_registers(obj, hdr, tmp1, tmp2); + assert_different_registers(obj, hdr, tmp1, tmp2, t0); // Check if we would have space on lock-stack for the object. lwu(tmp1, Address(xthread, JavaThread::lock_stack_top_offset())); @@ -4641,16 +4685,16 @@ sw(tmp1, Address(xthread, JavaThread::lock_stack_top_offset())); } -// Implements fast-unlocking. +// Implements ligthweight-unlocking. // Branches to slow upon failure. // Falls through upon success. // // - obj: the object to be unlocked // - hdr: the (pre-loaded) header of the object // - tmp1, tmp2: temporary registers -void MacroAssembler::fast_unlock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) { +void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) { assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); - assert_different_registers(obj, hdr, tmp1, tmp2); + assert_different_registers(obj, hdr, tmp1, tmp2, t0); #ifdef ASSERT { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -596,7 +596,9 @@ void NAME(Register Rs1, Register Rs2, const address dest) { \ assert_cond(dest != nullptr); \ int64_t offset = dest - pc(); \ - guarantee(is_simm13(offset) && ((offset % 2) == 0), "offset is invalid."); \ + guarantee(is_simm13(offset) && is_even(offset), \ + "offset is invalid: is_simm_13: %s offset: " INT64_FORMAT, \ + BOOL_TO_STR(is_simm13(offset)), offset); \ Assembler::NAME(Rs1, Rs2, offset); \ } \ INSN_ENTRY_RELOC(void, NAME(Register Rs1, Register Rs2, address dest, relocInfo::relocType rtype)) \ @@ -761,6 +763,10 @@ void orrw(Register Rd, Register Rs1, Register Rs2); void xorrw(Register Rd, Register Rs1, Register Rs2); + // logic with negate + void andn(Register Rd, Register Rs1, Register Rs2); + void orn(Register Rd, Register Rs1, Register Rs2); + // revb void revb_h_h(Register Rd, Register Rs, Register tmp = t0); // reverse bytes in halfword in lower 16 bits, sign-extend void revb_w_w(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); // reverse bytes in lower word, sign-extend @@ -772,6 +778,7 @@ void revb(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); // reverse bytes in doubleword void ror_imm(Register dst, Register src, uint32_t shift, Register tmp = t0); + void rolw_imm(Register dst, Register src, uint32_t, Register tmp = t0); void andi(Register Rd, Register Rn, int64_t imm, Register tmp = t0); void orptr(Address adr, RegisterOrConstant src, Register tmp1 = t0, Register tmp2 = t1); @@ -1217,7 +1224,7 @@ void shadd(Register Rd, Register Rs1, Register Rs2, Register tmp, int shamt); // test single bit in Rs, result is set to Rd - void test_bit(Register Rd, Register Rs, uint32_t bit_pos, Register tmp = t0); + void test_bit(Register Rd, Register Rs, uint32_t bit_pos); // Here the float instructions with safe deal with some exceptions. // e.g. convert from NaN, +Inf, -Inf to int, float, double @@ -1434,8 +1441,8 @@ void store_conditional(Register addr, Register new_val, enum operand_size size, Assembler::Aqrl release); public: - void fast_lock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow); - void fast_unlock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow); + void lightweight_lock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow); + void lightweight_unlock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow); }; #ifdef ASSERT diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/riscv.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/riscv.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/riscv.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/riscv.ad 2024-01-16 16:19:00.000000000 +0000 @@ -2431,223 +2431,6 @@ } %} - // Use cr register to indicate the fast_lock result: zero for success; non-zero for failure. - enc_class riscv_enc_fast_lock(iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2) %{ - C2_MacroAssembler _masm(&cbuf); - Register flag = t1; - Register oop = as_Register($object$$reg); - Register box = as_Register($box$$reg); - Register disp_hdr = as_Register($tmp1$$reg); - Register tmp = as_Register($tmp2$$reg); - Label cont; - Label object_has_monitor; - Label count, no_count; - - assert_different_registers(oop, box, tmp, disp_hdr, t0); - - // Load markWord from object into displaced_header. - __ ld(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); - - if (DiagnoseSyncOnValueBasedClasses != 0) { - __ load_klass(flag, oop); - __ lwu(flag, Address(flag, Klass::access_flags_offset())); - __ test_bit(flag, flag, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS), tmp /* tmp */); - __ bnez(flag, cont, true /* is_far */); - } - - // Check for existing monitor - __ test_bit(t0, disp_hdr, exact_log2(markWord::monitor_value)); - __ bnez(t0, object_has_monitor); - - if (LockingMode == LM_MONITOR) { - __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow-path - __ j(cont); - } else if (LockingMode == LM_LEGACY) { - // Set tmp to be (markWord of object | UNLOCK_VALUE). - __ ori(tmp, disp_hdr, markWord::unlocked_value); - - // Initialize the box. (Must happen before we update the object mark!) - __ sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); - - // Compare object markWord with an unlocked value (tmp) and if - // equal exchange the stack address of our box with object markWord. - // On failure disp_hdr contains the possibly locked markWord. - __ cmpxchg(/*memory address*/oop, /*expected value*/tmp, /*new value*/box, Assembler::int64, Assembler::aq, - Assembler::rl, /*result*/disp_hdr); - __ mv(flag, zr); - __ beq(disp_hdr, tmp, cont); // prepare zero flag and goto cont if we won the cas - - assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); - - // If the compare-and-exchange succeeded, then we found an unlocked - // object, will have now locked it will continue at label cont - // We did not see an unlocked object so try the fast recursive case. - - // Check if the owner is self by comparing the value in the - // markWord of object (disp_hdr) with the stack pointer. - __ sub(disp_hdr, disp_hdr, sp); - __ mv(tmp, (intptr_t) (~(os::vm_page_size()-1) | (uintptr_t)markWord::lock_mask_in_place)); - // If (mark & lock_mask) == 0 and mark - sp < page_size, we are stack-locking and goto cont, - // hence we can store 0 as the displaced header in the box, which indicates that it is a - // recursive lock. - __ andr(tmp/*==0?*/, disp_hdr, tmp); - __ sd(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); - __ mv(flag, tmp); // we can use the value of tmp as the result here - __ j(cont); - } else { - assert(LockingMode == LM_LIGHTWEIGHT, ""); - Label slow; - __ fast_lock(oop, disp_hdr, tmp, t0, slow); - - // Indicate success on completion. - __ mv(flag, zr); - __ j(count); - __ bind(slow); - __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow-path - __ j(no_count); - } - - // Handle existing monitor. - __ bind(object_has_monitor); - // The object's monitor m is unlocked iff m->owner == NULL, - // otherwise m->owner may contain a thread or a stack address. - // - // Try to CAS m->owner from NULL to current thread. - __ add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset()) - markWord::monitor_value)); - __ cmpxchg(/*memory address*/tmp, /*expected value*/zr, /*new value*/xthread, Assembler::int64, Assembler::aq, - Assembler::rl, /*result*/flag); // cas succeeds if flag == zr(expected) - - if (LockingMode != LM_LIGHTWEIGHT) { - // Store a non-null value into the box to avoid looking like a re-entrant - // lock. The fast-path monitor unlock code checks for - // markWord::monitor_value so use markWord::unused_mark which has the - // relevant bit set, and also matches ObjectSynchronizer::slow_enter. - __ mv(tmp, (address)markWord::unused_mark().value()); - __ sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); - } - - __ beqz(flag, cont); // CAS success means locking succeeded - - __ bne(flag, xthread, cont); // Check for recursive locking - - // Recursive lock case - __ mv(flag, zr); - __ increment(Address(disp_hdr, in_bytes(ObjectMonitor::recursions_offset()) - markWord::monitor_value), 1, t0, tmp); - - __ bind(cont); - // zero flag indicates success - // non-zero flag indicates failure - __ bnez(flag, no_count); - - __ bind(count); - __ increment(Address(xthread, JavaThread::held_monitor_count_offset()), 1, t0, tmp); - - __ bind(no_count); - %} - - // Use cr register to indicate the fast_unlock result: zero for success; non-zero for failure. - enc_class riscv_enc_fast_unlock(iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2) %{ - C2_MacroAssembler _masm(&cbuf); - Register flag = t1; - Register oop = as_Register($object$$reg); - Register box = as_Register($box$$reg); - Register disp_hdr = as_Register($tmp1$$reg); - Register tmp = as_Register($tmp2$$reg); - Label cont; - Label object_has_monitor; - Label count, no_count; - - assert_different_registers(oop, box, tmp, disp_hdr, flag); - - if (LockingMode == LM_LEGACY) { - // Find the lock address and load the displaced header from the stack. - __ ld(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); - - // If the displaced header is 0, we have a recursive unlock. - __ mv(flag, disp_hdr); - __ beqz(disp_hdr, cont); - } - - // Handle existing monitor. - __ ld(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); - __ test_bit(t0, tmp, exact_log2(markWord::monitor_value)); - __ bnez(t0, object_has_monitor); - - if (LockingMode == LM_MONITOR) { - __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow path - __ j(cont); - } else if (LockingMode == LM_LEGACY) { - // Check if it is still a light weight lock, this is true if we - // see the stack address of the basicLock in the markWord of the - // object. - - __ cmpxchg(/*memory address*/oop, /*expected value*/box, /*new value*/disp_hdr, Assembler::int64, Assembler::relaxed, - Assembler::rl, /*result*/tmp); - __ xorr(flag, box, tmp); // box == tmp if cas succeeds - __ j(cont); - } else { - assert(LockingMode == LM_LIGHTWEIGHT, ""); - Label slow; - __ fast_unlock(oop, tmp, box, disp_hdr, slow); - - // Indicate success on completion. - __ mv(flag, zr); - __ j(count); - __ bind(slow); - __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow path - __ j(no_count); - } - - assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); - - // Handle existing monitor. - __ bind(object_has_monitor); - STATIC_ASSERT(markWord::monitor_value <= INT_MAX); - __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor - - if (LockingMode == LM_LIGHTWEIGHT) { - // If the owner is anonymous, we need to fix it -- in an outline stub. - Register tmp2 = disp_hdr; - __ ld(tmp2, Address(tmp, ObjectMonitor::owner_offset())); - __ test_bit(t0, tmp2, exact_log2(ObjectMonitor::ANONYMOUS_OWNER)); - C2HandleAnonOMOwnerStub* stub = new (Compile::current()->comp_arena()) C2HandleAnonOMOwnerStub(tmp, tmp2); - Compile::current()->output()->add_stub(stub); - __ bnez(t0, stub->entry(), /* is_far */ true); - __ bind(stub->continuation()); - } - - __ ld(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); - - Label notRecursive; - __ beqz(disp_hdr, notRecursive); // Will be 0 if not recursive. - - // Recursive lock - __ addi(disp_hdr, disp_hdr, -1); - __ sd(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); - __ mv(flag, zr); - __ j(cont); - - __ bind(notRecursive); - __ ld(flag, Address(tmp, ObjectMonitor::EntryList_offset())); - __ ld(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset())); - __ orr(flag, flag, disp_hdr); // Will be 0 if both are 0. - __ bnez(flag, cont); - // need a release store here - __ la(tmp, Address(tmp, ObjectMonitor::owner_offset())); - __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); - __ sd(zr, Address(tmp)); // set unowned - - __ bind(cont); - // zero flag indicates success - // non-zero flag indicates failure - __ bnez(flag, no_count); - - __ bind(count); - __ decrement(Address(xthread, JavaThread::held_monitor_count_offset()), 1, t0, tmp); - - __ bind(no_count); - %} - // arithmetic encodings enc_class riscv_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ @@ -6859,6 +6642,21 @@ ins_pipe(lmul_reg_reg); %} +instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2) +%{ + match(Set dst (UMulHiL src1 src2)); + ins_cost(IMUL_COST); + format %{ "mulhu $dst, $src1, $src2\t# umulhi, #@umulHiL_rReg" %} + + ins_encode %{ + __ mulhu(as_Register($dst$$reg), + as_Register($src1$$reg), + as_Register($src2$$reg)); + %} + + ins_pipe(lmul_reg_reg); +%} + // Integer Divide instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ @@ -10374,15 +10172,17 @@ // inlined locking and unlocking // using t1 as the 'flag' register to bridge the BoolNode producers and consumers -instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2) +instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3) %{ match(Set cr (FastLock object box)); - effect(TEMP tmp1, TEMP tmp2); + effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); ins_cost(LOAD_COST * 2 + STORE_COST * 3 + ALU_COST * 6 + BRANCH_COST * 3); - format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2, #@cmpFastLock" %} + format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2,$tmp3, #@cmpFastLock" %} - ins_encode(riscv_enc_fast_lock(object, box, tmp1, tmp2)); + ins_encode %{ + __ fast_lock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); + %} ins_pipe(pipe_serial); %} @@ -10396,7 +10196,9 @@ ins_cost(LOAD_COST * 2 + STORE_COST + ALU_COST * 2 + BRANCH_COST * 4); format %{ "fastunlock $object,$box\t! kills $tmp1, $tmp2, #@cmpFastUnlock" %} - ins_encode(riscv_enc_fast_unlock(object, box, tmp1, tmp2)); + ins_encode %{ + __ fast_unlock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register); + %} ins_pipe(pipe_serial); %} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/riscv_v.ad openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/riscv_v.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/riscv_v.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/riscv_v.ad 2024-01-16 16:19:00.000000000 +0000 @@ -2954,11 +2954,9 @@ 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_helper(bt, Matcher::vector_length(this)); - __ vmclr_m(as_VectorRegister($dst$$reg)); - __ vsetvli(t0, $src$$Register, sew); - __ vmset_m(as_VectorRegister($dst$$reg)); + __ vid_v(as_VectorRegister($dst$$reg)); + __ vmsltu_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), $src$$Register); %} ins_pipe(pipe_slow); %} @@ -2968,26 +2966,30 @@ 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_helper(bt, Matcher::vector_length(this)); - __ vmclr_m(as_VectorRegister($dst$$reg)); - __ vsetvli(t0, $src$$Register, sew); - __ vmset_m(as_VectorRegister($dst$$reg)); + __ vid_v(as_VectorRegister($dst$$reg)); + __ vmsltu_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), $src$$Register); %} ins_pipe(pipe_slow); %} instruct vmask_gen_imm(vRegMask dst, immL con) %{ + predicate(n->in(1)->get_long() <= 16 || + n->in(1)->get_long() == Matcher::vector_length(n)); match(Set dst (VectorMaskGen con)); format %{ "vmask_gen_imm $dst, $con" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); - if ($con$$constant != Matcher::vector_length(this)) { - __ vsetvli_helper(bt, Matcher::vector_length(this)); + __ vsetvli_helper(bt, Matcher::vector_length(this)); + if ((uint)($con$$constant) == 0) { __ vmclr_m(as_VectorRegister($dst$$reg)); + } else if ((uint)($con$$constant) == Matcher::vector_length(this)) { + __ vmset_m(as_VectorRegister($dst$$reg)); + } else { + assert((uint)($con$$constant) < Matcher::vector_length(this), "unsupported input lane_cnt"); + __ vid_v(as_VectorRegister($dst$$reg)); + __ vmsleu_vi(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), (uint)($con$$constant) - 1); } - __ vsetvli_helper(bt, (uint)($con$$constant)); - __ vmset_m(as_VectorRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} @@ -3197,13 +3199,12 @@ effect(TEMP_DEF dst); format %{ "vcvtStoX_fp_extend $dst, $src" %} ins_encode %{ - __ vsetvli_helper(T_SHORT, Matcher::vector_length(this), Assembler::mf2); + BasicType bt = Matcher::vector_element_basic_type(this); + __ integer_extend_v(as_VectorRegister($dst$$reg), (bt == T_FLOAT ? T_INT : T_LONG), + Matcher::vector_length(this), as_VectorRegister($src$$reg), T_SHORT); + __ vsetvli_helper(bt, Matcher::vector_length(this)); __ csrwi(CSR_FRM, C2_MacroAssembler::rne); - __ vfwcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); - if (Matcher::vector_element_basic_type(this) == T_DOUBLE) { - __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2); - __ vfwcvt_f_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); - } + __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} @@ -3309,12 +3310,11 @@ effect(TEMP_DEF dst, TEMP v0); format %{ "vcvtFtoX_narrow $dst, $src" %} ins_encode %{ - __ vsetvli_helper(T_SHORT, Matcher::vector_length(this), Assembler::mf2); - __ vfncvt_rtz_x_f_w_safe(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); - if (Matcher::vector_element_basic_type(this) == T_BYTE) { - __ vsetvli_helper(T_BYTE, Matcher::vector_length(this), Assembler::mf2); - __ vncvt_x_x_w(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); - } + __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this)); + __ vfcvt_rtz_x_f_v_safe(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); + BasicType bt = Matcher::vector_element_basic_type(this); + __ integer_narrow_v(as_VectorRegister($dst$$reg), bt, Matcher::vector_length(this), + as_VectorRegister($dst$$reg), T_INT); %} ins_pipe(pipe_slow); %} @@ -3337,8 +3337,11 @@ effect(TEMP_DEF dst, TEMP v0); format %{ "vcvtFtoL $dst, $src" %} ins_encode %{ + __ vsetvli_helper(T_LONG, Matcher::vector_length(this)); + __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2); - __ vfwcvt_rtz_x_f_v_safe(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); + __ vmfeq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg)); + __ vfwcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), Assembler::v0_t); %} ins_pipe(pipe_slow); %} @@ -3366,8 +3369,11 @@ effect(TEMP_DEF dst, TEMP v0); format %{ "vcvtDtoX_narrow $dst, $src" %} ins_encode %{ + __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this)); + __ vmfeq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg)); __ vsetvli_helper(T_INT, Matcher::vector_length(this), Assembler::mf2); - __ vfncvt_rtz_x_f_w_safe(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); + __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); + __ vfncvt_rtz_x_f_w(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), Assembler::v0_t); BasicType bt = Matcher::vector_element_basic_type(this); if (bt == T_BYTE || bt == T_SHORT) { __ integer_narrow_v(as_VectorRegister($dst$$reg), bt, Matcher::vector_length(this), @@ -3551,18 +3557,16 @@ // ------------------------------ Compress/Expand Operations ------------------- -instruct mcompress(vRegMask dst, vRegMask src, iRegLNoSp tmp) %{ +instruct mcompress(vRegMask dst, vRegMask src, vReg tmp) %{ match(Set dst (CompressM src)); - effect(TEMP_DEF dst, TEMP tmp); + effect(TEMP tmp); format %{ "mcompress $dst, $src\t# KILL $tmp" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); - Assembler::SEW sew = Assembler::elemtype_to_sew(bt); __ vsetvli_helper(bt, Matcher::vector_length(this)); - __ vmclr_m(as_VectorRegister($dst$$reg)); - __ vcpop_m($tmp$$Register, as_VectorRegister($src$$reg)); - __ vsetvli(t0, $tmp$$Register, sew); - __ vmset_m(as_VectorRegister($dst$$reg)); + __ vid_v(as_VectorRegister($tmp$$reg)); + __ vcpop_m(t0, as_VectorRegister($src$$reg)); + __ vmsltu_vx(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), t0); %} ins_pipe(pipe_slow); %} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1650,6 +1650,7 @@ const Register obj_reg = x9; // Will contain the oop const Register lock_reg = x30; // Address of compiler lock object (BasicLock) const Register old_hdr = x30; // value of old header at unlock time + const Register lock_tmp = x31; // Temporary used by lightweight_lock/unlock const Register tmp = ra; Label slow_path_lock; @@ -1701,7 +1702,7 @@ } else { assert(LockingMode == LM_LIGHTWEIGHT, ""); __ ld(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ fast_lock(obj_reg, swap_reg, tmp, t0, slow_path_lock); + __ lightweight_lock(obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock); } __ bind(count); @@ -1829,7 +1830,7 @@ __ ld(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes())); __ test_bit(t0, old_hdr, exact_log2(markWord::monitor_value)); __ bnez(t0, slow_path_unlock); - __ fast_unlock(obj_reg, old_hdr, swap_reg, t0, slow_path_unlock); + __ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock); __ decrement(Address(xthread, JavaThread::held_monitor_count_offset())); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3949,6 +3949,375 @@ return start; } + // Set of L registers that correspond to a contiguous memory area. + // Each 64-bit register typically corresponds to 2 32-bit integers. + template + class RegCache { + private: + MacroAssembler *_masm; + Register _regs[L]; + + public: + RegCache(MacroAssembler *masm, RegSet rs): _masm(masm) { + assert(rs.size() == L, "%u registers are used to cache %u 4-byte data", rs.size(), 2 * L); + auto it = rs.begin(); + for (auto &r: _regs) { + r = *it; + ++it; + } + } + + // generate load for the i'th register + void gen_load(uint i, Register base) { + assert(i < L, "invalid i: %u", i); + __ ld(_regs[i], Address(base, 8 * i)); + } + + // add i'th 32-bit integer to dest + void add_u32(const Register dest, uint i, const Register rtmp = t0) { + assert(i < 2 * L, "invalid i: %u", i); + + if (is_even(i)) { + // Use the bottom 32 bits. No need to mask off the top 32 bits + // as addw will do the right thing. + __ addw(dest, dest, _regs[i / 2]); + } else { + // Use the top 32 bits by right-shifting them. + __ srli(rtmp, _regs[i / 2], 32); + __ addw(dest, dest, rtmp); + } + } + }; + + typedef RegCache<8> BufRegCache; + + // a += value + x + ac; + // a = Integer.rotateLeft(a, s) + b; + void m5_FF_GG_HH_II_epilogue(BufRegCache& reg_cache, + Register a, Register b, Register c, Register d, + int k, int s, int t, + Register value) { + // a += ac + __ addw(a, a, t, t1); + + // a += x; + reg_cache.add_u32(a, k); + // a += value; + __ addw(a, a, value); + + // a = Integer.rotateLeft(a, s) + b; + __ rolw_imm(a, a, s); + __ addw(a, a, b); + } + + // a += ((b & c) | ((~b) & d)) + x + ac; + // a = Integer.rotateLeft(a, s) + b; + void md5_FF(BufRegCache& reg_cache, + Register a, Register b, Register c, Register d, + int k, int s, int t, + Register rtmp1, Register rtmp2) { + // rtmp1 = b & c + __ andr(rtmp1, b, c); + + // rtmp2 = (~b) & d + __ andn(rtmp2, d, b); + + // rtmp1 = (b & c) | ((~b) & d) + __ orr(rtmp1, rtmp1, rtmp2); + + m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1); + } + + // a += ((b & d) | (c & (~d))) + x + ac; + // a = Integer.rotateLeft(a, s) + b; + void md5_GG(BufRegCache& reg_cache, + Register a, Register b, Register c, Register d, + int k, int s, int t, + Register rtmp1, Register rtmp2) { + // rtmp1 = b & d + __ andr(rtmp1, b, d); + + // rtmp2 = c & (~d) + __ andn(rtmp2, c, d); + + // rtmp1 = (b & d) | (c & (~d)) + __ orr(rtmp1, rtmp1, rtmp2); + + m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1); + } + + // a += ((b ^ c) ^ d) + x + ac; + // a = Integer.rotateLeft(a, s) + b; + void md5_HH(BufRegCache& reg_cache, + Register a, Register b, Register c, Register d, + int k, int s, int t, + Register rtmp1, Register rtmp2) { + // rtmp1 = (b ^ c) ^ d + __ xorr(rtmp2, b, c); + __ xorr(rtmp1, rtmp2, d); + + m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1); + } + + // a += (c ^ (b | (~d))) + x + ac; + // a = Integer.rotateLeft(a, s) + b; + void md5_II(BufRegCache& reg_cache, + Register a, Register b, Register c, Register d, + int k, int s, int t, + Register rtmp1, Register rtmp2) { + // rtmp1 = c ^ (b | (~d)) + __ orn(rtmp2, b, d); + __ xorr(rtmp1, c, rtmp2); + + m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1); + } + + // Arguments: + // + // Inputs: + // c_rarg0 - byte[] source+offset + // c_rarg1 - int[] SHA.state + // c_rarg2 - int offset (multi_block == True) + // c_rarg3 - int limit (multi_block == True) + // + // Registers: + // x0 zero (zero) + // x1 ra (return address) + // x2 sp (stack pointer) + // x3 gp (global pointer) + // x4 tp (thread pointer) + // x5 t0 (tmp register) + // x6 t1 (tmp register) + // x7 t2 state0 + // x8 f0/s0 (frame pointer) + // x9 s1 + // x10 a0 rtmp1 / c_rarg0 + // x11 a1 rtmp2 / c_rarg1 + // x12 a2 a / c_rarg2 + // x13 a3 b / c_rarg3 + // x14 a4 c + // x15 a5 d + // x16 a6 buf + // x17 a7 state + // x18 s2 ofs [saved-reg] (multi_block == True) + // x19 s3 limit [saved-reg] (multi_block == True) + // x20 s4 state1 [saved-reg] + // x21 s5 state2 [saved-reg] + // x22 s6 state3 [saved-reg] + // x23 s7 + // x24 s8 buf0 [saved-reg] + // x25 s9 buf1 [saved-reg] + // x26 s10 buf2 [saved-reg] + // x27 s11 buf3 [saved-reg] + // x28 t3 buf4 + // x29 t4 buf5 + // x30 t5 buf6 + // x31 t6 buf7 + address generate_md5_implCompress(bool multi_block, const char *name) { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ pc(); + + // rotation constants + const int S11 = 7; + const int S12 = 12; + const int S13 = 17; + const int S14 = 22; + const int S21 = 5; + const int S22 = 9; + const int S23 = 14; + const int S24 = 20; + const int S31 = 4; + const int S32 = 11; + const int S33 = 16; + const int S34 = 23; + const int S41 = 6; + const int S42 = 10; + const int S43 = 15; + const int S44 = 21; + + const int64_t mask32 = 0xffffffff; + + Register buf_arg = c_rarg0; // a0 + Register state_arg = c_rarg1; // a1 + Register ofs_arg = c_rarg2; // a2 + Register limit_arg = c_rarg3; // a3 + + // we'll copy the args to these registers to free up a0-a3 + // to use for other values manipulated by instructions + // that can be compressed + Register buf = x16; // a6 + Register state = x17; // a7 + Register ofs = x18; // s2 + Register limit = x19; // s3 + + // using x12->15 to allow compressed instructions + Register a = x12; // a2 + Register b = x13; // a3 + Register c = x14; // a4 + Register d = x15; // a5 + + Register state0 = x7; // t2 + Register state1 = x20; // s4 + Register state2 = x21; // s5 + Register state3 = x22; // s6 + + // using x10->x11 to allow compressed instructions + Register rtmp1 = x10; // a0 + Register rtmp2 = x11; // a1 + + RegSet reg_cache_saved_regs = RegSet::of(x24, x25, x26, x27); // s8, s9, s10, s11 + RegSet reg_cache_regs; + reg_cache_regs += reg_cache_saved_regs; + reg_cache_regs += RegSet::of(x28, x29, x30, x31); // t3, t4, t5, t6 + BufRegCache reg_cache(_masm, reg_cache_regs); + + RegSet saved_regs; + if (multi_block) { + saved_regs += RegSet::of(ofs, limit); + } + saved_regs += RegSet::of(state1, state2, state3); + saved_regs += reg_cache_saved_regs; + + __ push_reg(saved_regs, sp); + + __ mv(buf, buf_arg); + __ mv(state, state_arg); + if (multi_block) { + __ mv(ofs, ofs_arg); + __ mv(limit, limit_arg); + } + + // to minimize the number of memory operations: + // read the 4 state 4-byte values in pairs, with a single ld, + // and split them into 2 registers + __ mv(t0, mask32); + __ ld(state0, Address(state)); + __ srli(state1, state0, 32); + __ andr(state0, state0, t0); + __ ld(state2, Address(state, 8)); + __ srli(state3, state2, 32); + __ andr(state2, state2, t0); + + Label md5_loop; + __ BIND(md5_loop); + + __ mv(a, state0); + __ mv(b, state1); + __ mv(c, state2); + __ mv(d, state3); + + // Round 1 + reg_cache.gen_load(0, buf); + md5_FF(reg_cache, a, b, c, d, 0, S11, 0xd76aa478, rtmp1, rtmp2); + md5_FF(reg_cache, d, a, b, c, 1, S12, 0xe8c7b756, rtmp1, rtmp2); + reg_cache.gen_load(1, buf); + md5_FF(reg_cache, c, d, a, b, 2, S13, 0x242070db, rtmp1, rtmp2); + md5_FF(reg_cache, b, c, d, a, 3, S14, 0xc1bdceee, rtmp1, rtmp2); + reg_cache.gen_load(2, buf); + md5_FF(reg_cache, a, b, c, d, 4, S11, 0xf57c0faf, rtmp1, rtmp2); + md5_FF(reg_cache, d, a, b, c, 5, S12, 0x4787c62a, rtmp1, rtmp2); + reg_cache.gen_load(3, buf); + md5_FF(reg_cache, c, d, a, b, 6, S13, 0xa8304613, rtmp1, rtmp2); + md5_FF(reg_cache, b, c, d, a, 7, S14, 0xfd469501, rtmp1, rtmp2); + reg_cache.gen_load(4, buf); + md5_FF(reg_cache, a, b, c, d, 8, S11, 0x698098d8, rtmp1, rtmp2); + md5_FF(reg_cache, d, a, b, c, 9, S12, 0x8b44f7af, rtmp1, rtmp2); + reg_cache.gen_load(5, buf); + md5_FF(reg_cache, c, d, a, b, 10, S13, 0xffff5bb1, rtmp1, rtmp2); + md5_FF(reg_cache, b, c, d, a, 11, S14, 0x895cd7be, rtmp1, rtmp2); + reg_cache.gen_load(6, buf); + md5_FF(reg_cache, a, b, c, d, 12, S11, 0x6b901122, rtmp1, rtmp2); + md5_FF(reg_cache, d, a, b, c, 13, S12, 0xfd987193, rtmp1, rtmp2); + reg_cache.gen_load(7, buf); + md5_FF(reg_cache, c, d, a, b, 14, S13, 0xa679438e, rtmp1, rtmp2); + md5_FF(reg_cache, b, c, d, a, 15, S14, 0x49b40821, rtmp1, rtmp2); + + // Round 2 + md5_GG(reg_cache, a, b, c, d, 1, S21, 0xf61e2562, rtmp1, rtmp2); + md5_GG(reg_cache, d, a, b, c, 6, S22, 0xc040b340, rtmp1, rtmp2); + md5_GG(reg_cache, c, d, a, b, 11, S23, 0x265e5a51, rtmp1, rtmp2); + md5_GG(reg_cache, b, c, d, a, 0, S24, 0xe9b6c7aa, rtmp1, rtmp2); + md5_GG(reg_cache, a, b, c, d, 5, S21, 0xd62f105d, rtmp1, rtmp2); + md5_GG(reg_cache, d, a, b, c, 10, S22, 0x02441453, rtmp1, rtmp2); + md5_GG(reg_cache, c, d, a, b, 15, S23, 0xd8a1e681, rtmp1, rtmp2); + md5_GG(reg_cache, b, c, d, a, 4, S24, 0xe7d3fbc8, rtmp1, rtmp2); + md5_GG(reg_cache, a, b, c, d, 9, S21, 0x21e1cde6, rtmp1, rtmp2); + md5_GG(reg_cache, d, a, b, c, 14, S22, 0xc33707d6, rtmp1, rtmp2); + md5_GG(reg_cache, c, d, a, b, 3, S23, 0xf4d50d87, rtmp1, rtmp2); + md5_GG(reg_cache, b, c, d, a, 8, S24, 0x455a14ed, rtmp1, rtmp2); + md5_GG(reg_cache, a, b, c, d, 13, S21, 0xa9e3e905, rtmp1, rtmp2); + md5_GG(reg_cache, d, a, b, c, 2, S22, 0xfcefa3f8, rtmp1, rtmp2); + md5_GG(reg_cache, c, d, a, b, 7, S23, 0x676f02d9, rtmp1, rtmp2); + md5_GG(reg_cache, b, c, d, a, 12, S24, 0x8d2a4c8a, rtmp1, rtmp2); + + // Round 3 + md5_HH(reg_cache, a, b, c, d, 5, S31, 0xfffa3942, rtmp1, rtmp2); + md5_HH(reg_cache, d, a, b, c, 8, S32, 0x8771f681, rtmp1, rtmp2); + md5_HH(reg_cache, c, d, a, b, 11, S33, 0x6d9d6122, rtmp1, rtmp2); + md5_HH(reg_cache, b, c, d, a, 14, S34, 0xfde5380c, rtmp1, rtmp2); + md5_HH(reg_cache, a, b, c, d, 1, S31, 0xa4beea44, rtmp1, rtmp2); + md5_HH(reg_cache, d, a, b, c, 4, S32, 0x4bdecfa9, rtmp1, rtmp2); + md5_HH(reg_cache, c, d, a, b, 7, S33, 0xf6bb4b60, rtmp1, rtmp2); + md5_HH(reg_cache, b, c, d, a, 10, S34, 0xbebfbc70, rtmp1, rtmp2); + md5_HH(reg_cache, a, b, c, d, 13, S31, 0x289b7ec6, rtmp1, rtmp2); + md5_HH(reg_cache, d, a, b, c, 0, S32, 0xeaa127fa, rtmp1, rtmp2); + md5_HH(reg_cache, c, d, a, b, 3, S33, 0xd4ef3085, rtmp1, rtmp2); + md5_HH(reg_cache, b, c, d, a, 6, S34, 0x04881d05, rtmp1, rtmp2); + md5_HH(reg_cache, a, b, c, d, 9, S31, 0xd9d4d039, rtmp1, rtmp2); + md5_HH(reg_cache, d, a, b, c, 12, S32, 0xe6db99e5, rtmp1, rtmp2); + md5_HH(reg_cache, c, d, a, b, 15, S33, 0x1fa27cf8, rtmp1, rtmp2); + md5_HH(reg_cache, b, c, d, a, 2, S34, 0xc4ac5665, rtmp1, rtmp2); + + // Round 4 + md5_II(reg_cache, a, b, c, d, 0, S41, 0xf4292244, rtmp1, rtmp2); + md5_II(reg_cache, d, a, b, c, 7, S42, 0x432aff97, rtmp1, rtmp2); + md5_II(reg_cache, c, d, a, b, 14, S43, 0xab9423a7, rtmp1, rtmp2); + md5_II(reg_cache, b, c, d, a, 5, S44, 0xfc93a039, rtmp1, rtmp2); + md5_II(reg_cache, a, b, c, d, 12, S41, 0x655b59c3, rtmp1, rtmp2); + md5_II(reg_cache, d, a, b, c, 3, S42, 0x8f0ccc92, rtmp1, rtmp2); + md5_II(reg_cache, c, d, a, b, 10, S43, 0xffeff47d, rtmp1, rtmp2); + md5_II(reg_cache, b, c, d, a, 1, S44, 0x85845dd1, rtmp1, rtmp2); + md5_II(reg_cache, a, b, c, d, 8, S41, 0x6fa87e4f, rtmp1, rtmp2); + md5_II(reg_cache, d, a, b, c, 15, S42, 0xfe2ce6e0, rtmp1, rtmp2); + md5_II(reg_cache, c, d, a, b, 6, S43, 0xa3014314, rtmp1, rtmp2); + md5_II(reg_cache, b, c, d, a, 13, S44, 0x4e0811a1, rtmp1, rtmp2); + md5_II(reg_cache, a, b, c, d, 4, S41, 0xf7537e82, rtmp1, rtmp2); + md5_II(reg_cache, d, a, b, c, 11, S42, 0xbd3af235, rtmp1, rtmp2); + md5_II(reg_cache, c, d, a, b, 2, S43, 0x2ad7d2bb, rtmp1, rtmp2); + md5_II(reg_cache, b, c, d, a, 9, S44, 0xeb86d391, rtmp1, rtmp2); + + __ addw(state0, state0, a); + __ addw(state1, state1, b); + __ addw(state2, state2, c); + __ addw(state3, state3, d); + + if (multi_block) { + __ addi(buf, buf, 64); + __ addi(ofs, ofs, 64); + // if (ofs <= limit) goto m5_loop + __ bge(limit, ofs, md5_loop); + __ mv(c_rarg0, ofs); // return ofs + } + + // to minimize the number of memory operations: + // write back the 4 state 4-byte values in pairs, with a single sd + __ mv(t0, mask32); + __ andr(state0, state0, t0); + __ slli(state1, state1, 32); + __ orr(state0, state0, state1); + __ sd(state0, Address(state)); + __ andr(state2, state2, t0); + __ slli(state3, state3, 32); + __ orr(state2, state2, state3); + __ sd(state2, Address(state, 8)); + + __ pop_reg(saved_regs, sp); + __ ret(); + + return (address) start; + } + #if INCLUDE_JFR static void jfr_prologue(address the_pc, MacroAssembler* _masm, Register thread) { @@ -4163,6 +4532,11 @@ generate_compare_long_strings(); generate_string_indexof_stubs(); + + if (UseMD5Intrinsics) { + StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress"); + StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB"); + } #endif // COMPILER2_OR_JVMCI } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -600,7 +600,7 @@ // monitor entry size: see picture of stack set // (generate_method_entry) and frame_amd64.hpp - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); // total overhead size: entry_size + (saved fp through expr stack // bottom). be sure to change this if you add/subtract anything @@ -673,7 +673,7 @@ // synchronize method const Address access_flags(xmethod, Method::access_flags_offset()); const Address monitor_block_top(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); #ifdef ASSERT __ lwu(x10, access_flags); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/templateTable_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/templateTable_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/templateTable_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/templateTable_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3739,7 +3739,7 @@ fp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( fp, frame::interpreter_frame_initial_sp_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); Label allocated; @@ -3837,7 +3837,7 @@ fp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( fp, frame::interpreter_frame_initial_sp_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); Label found; diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/vm_version_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/vm_version_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/riscv/vm_version_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/riscv/vm_version_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -171,9 +171,13 @@ FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); } - if (UseMD5Intrinsics) { - warning("MD5 intrinsics are not available on this CPU."); - FLAG_SET_DEFAULT(UseMD5Intrinsics, false); + if (UseVectorizedMismatchIntrinsic) { + warning("VectorizedMismatch intrinsic is not available on this CPU."); + FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); + } + + if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) { + FLAG_SET_DEFAULT(UseMD5Intrinsics, true); } if (UseRVV) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/assembler_s390.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/assembler_s390.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/assembler_s390.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/assembler_s390.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -140,7 +140,8 @@ 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"); + guarantee(is_in_range_of_RelAddr(target, pc, shortForm), + "target not within reach at " INTPTR_FORMAT ", distance = " INTX_FORMAT, p2i(pc), (target - pc) ); return (int)((target - pc)>>1); } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -83,60 +83,63 @@ if (breakAtEntry) z_illtrap(0xC1); } -void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { +void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) { const int hdr_offset = oopDesc::mark_offset_in_bytes(); - assert_different_registers(hdr, obj, disp_hdr); - verify_oop(obj, FILE_AND_LINE); + const Register tmp = Z_R1_scratch; + + assert_different_registers(Rmark, Roop, Rbox, tmp); + + verify_oop(Roop, FILE_AND_LINE); // Load object header. - z_lg(hdr, Address(obj, hdr_offset)); + z_lg(Rmark, Address(Roop, hdr_offset)); // Save object being locked into the BasicObjectLock... - z_stg(obj, Address(disp_hdr, BasicObjectLock::obj_offset())); + z_stg(Roop, Address(Rbox, BasicObjectLock::obj_offset())); if (DiagnoseSyncOnValueBasedClasses != 0) { - load_klass(Z_R1_scratch, obj); - testbit(Address(Z_R1_scratch, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); - z_btrue(slow_case); + load_klass(tmp, Roop); + testbit(Address(tmp, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + branch_optimized(Assembler::bcondAllOne, slow_case); } assert(LockingMode != LM_MONITOR, "LM_MONITOR is already handled, by emit_lock()"); if (LockingMode == LM_LIGHTWEIGHT) { - Unimplemented(); + lightweight_lock(Roop, Rmark, tmp, slow_case); } else if (LockingMode == LM_LEGACY) { NearLabel done; // and mark it as unlocked. - z_oill(hdr, markWord::unlocked_value); + z_oill(Rmark, markWord::unlocked_value); // Save unlocked object header into the displaced header location on the stack. - z_stg(hdr, Address(disp_hdr, (intptr_t) 0)); + z_stg(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes())); // Test if object header is still the same (i.e. unlocked), and if so, store the // displaced header address in the object header. If it is not the same, get the // object header instead. - z_csg(hdr, disp_hdr, hdr_offset, obj); + z_csg(Rmark, Rbox, hdr_offset, Roop); // If the object header was the same, we're done. branch_optimized(Assembler::bcondEqual, done); - // If the object header was not the same, it is now in the hdr register. + // If the object header was not the same, it is now in the Rmark register. // => Test if it is a stack pointer into the same stack (recursive locking), i.e.: // - // 1) (hdr & markWord::lock_mask_in_place) == 0 - // 2) rsp <= hdr - // 3) hdr <= rsp + page_size + // 1) (Rmark & markWord::lock_mask_in_place) == 0 + // 2) rsp <= Rmark + // 3) Rmark <= rsp + page_size // // These 3 tests can be done by evaluating the following expression: // - // (hdr - Z_SP) & (~(page_size-1) | markWord::lock_mask_in_place) + // (Rmark - Z_SP) & (~(page_size-1) | markWord::lock_mask_in_place) // // assuming both the stack pointer and page_size have their least // significant 2 bits cleared and page_size is a power of 2 - z_sgr(hdr, Z_SP); + z_sgr(Rmark, Z_SP); 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). + z_ngr(Rmark, 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). - z_stg(hdr, Address(disp_hdr, (intptr_t) 0)); + // location (null in the displaced Rmark location indicates recursive locking). + z_stg(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes())); // Otherwise we don't care about the result and handle locking via runtime call. branch_optimized(Assembler::bcondNotZero, slow_case); // done @@ -144,35 +147,41 @@ } } -void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { - const int aligned_mask = BytesPerWord -1; +void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) { const int hdr_offset = oopDesc::mark_offset_in_bytes(); - assert_different_registers(hdr, obj, disp_hdr); + + assert_different_registers(Rmark, Roop, Rbox); + NearLabel done; if (LockingMode != LM_LIGHTWEIGHT) { // 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. + z_ltg(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes())); + // If the loaded Rmark is null we had recursive locking, and we are done. z_bre(done); } // Load object. - z_lg(obj, Address(disp_hdr, BasicObjectLock::obj_offset())); - verify_oop(obj, FILE_AND_LINE); + z_lg(Roop, Address(Rbox, BasicObjectLock::obj_offset())); + verify_oop(Roop, FILE_AND_LINE); if (LockingMode == LM_LIGHTWEIGHT) { - Unimplemented(); - } else { + const Register tmp = Z_R1_scratch; + z_lg(Rmark, Address(Roop, hdr_offset)); + z_lgr(tmp, Rmark); + z_nill(tmp, markWord::monitor_value); + branch_optimized(Assembler::bcondNotZero, slow_case); + lightweight_unlock(Roop, Rmark, tmp, slow_case); + } else if (LockingMode == LM_LEGACY) { // Test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object. If the object header is not pointing to // the displaced header, get the object header instead. - z_csg(disp_hdr, hdr, hdr_offset, obj); + z_csg(Rbox, Rmark, hdr_offset, Roop); // If the object header was not pointing to the displaced header, // we do unlocking via runtime call. branch_optimized(Assembler::bcondNotEqual, slow_case); - // done } + // done bind(done); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -41,17 +41,18 @@ void initialize_body(Register objectFields, Register len_in_bytes, Register Rzero); // locking - // hdr : Used to hold locked markWord to be CASed into obj, contents destroyed. - // obj : Must point to the object to lock, contents preserved. - // disp_hdr: Must point to the displaced header location, contents preserved. - // Returns code offset at which to add null check debug information. - void lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case); + // Rmark : Used to hold locked markWord to be CASed into obj, contents destroyed. + // Roop : Must point to the object to lock, contents preserved. + // Rbox : Must point to the displaced header location, contents preserved. + // Z_R1_scratch : Used as temp and will be killed + void lock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case); // unlocking - // hdr : Used to hold original markWord to be CASed back into obj, contents destroyed. - // obj : Must point to the object to lock, contents preserved. - // disp_hdr: Must point to the displaced header location, contents destroyed. - void unlock_object(Register hdr, Register obj, Register lock, Label& slow_case); + // Rmark : Used to hold original markWord to be CASed back into obj, contents destroyed. + // Roop : Must point to the object to lock, contents preserved. + // Rbox : Must point to the displaced header location, contents destroyed. + // Z_R1_scratch : Used as temp and will be killed + void unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case); void initialize_object( Register obj, // result: Pointer to object after successful allocation. diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/downcallLinker_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/downcallLinker_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/downcallLinker_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/downcallLinker_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -23,8 +23,76 @@ */ #include "precompiled.hpp" +#include "asm/macroAssembler.inline.hpp" +#include "code/codeBlob.hpp" +#include "code/codeCache.hpp" +#include "code/vmreg.inline.hpp" +#include "compiler/oopMap.hpp" +#include "logging/logStream.hpp" +#include "memory/resourceArea.hpp" #include "prims/downcallLinker.hpp" -#include "utilities/debug.hpp" +#include "runtime/globals.hpp" +#include "runtime/stubCodeGenerator.hpp" + +#define __ _masm-> + +class DowncallStubGenerator : public StubCodeGenerator { + BasicType* _signature; + int _num_args; + BasicType _ret_bt; + const ABIDescriptor& _abi; + + const GrowableArray& _input_registers; + const GrowableArray& _output_registers; + + bool _needs_return_buffer; + int _captured_state_mask; + bool _needs_transition; + + int _frame_complete; + int _frame_size_slots; + OopMapSet* _oop_maps; + public: + DowncallStubGenerator(CodeBuffer* buffer, + BasicType* signature, + int num_args, + BasicType ret_bt, + const ABIDescriptor& abi, + const GrowableArray& input_registers, + const GrowableArray& output_registers, + bool needs_return_buffer, + int captured_state_mask, + bool needs_transition) + :StubCodeGenerator(buffer, PrintMethodHandleStubs), + _signature(signature), + _num_args(num_args), + _ret_bt(ret_bt), + _abi(abi), + _input_registers(input_registers), + _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) { + } + void generate(); + int frame_complete() const { + return _frame_complete; + } + + int framesize() const { + return (_frame_size_slots >> (LogBytesPerWord - LogBytesPerInt)); + } + + OopMapSet* oop_maps() const { + return _oop_maps; + } +}; + +static const int native_invoker_code_base_size = 512; +static const int native_invoker_size_per_args = 8; RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int num_args, @@ -35,6 +103,197 @@ bool needs_return_buffer, int captured_state_mask, bool needs_transition) { - Unimplemented(); - return nullptr; + + int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_args); + 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_transition); + g.generate(); + code.log_section_sizes("nep_invoker_blob"); + + RuntimeStub* stub = + RuntimeStub::new_runtime_stub("nep_invoker_blob", + &code, + g.frame_complete(), + g.framesize(), + g.oop_maps(), false); + +#ifndef PRODUCT + LogTarget(Trace, foreign, downcall) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + stub->print_on(&ls); + } +#endif + + return stub; +} + +void DowncallStubGenerator::generate() { + Register call_target_address = Z_R1_scratch, + tmp = Z_R0_scratch; + + VMStorage shuffle_reg = _abi._scratch1; + + JavaCallingConvention in_conv; + NativeCallingConvention out_conv(_input_registers); + ArgumentShuffle arg_shuffle(_signature, _num_args, _signature, _num_args, &in_conv, &out_conv, shuffle_reg); + +#ifndef PRODUCT + LogTarget(Trace, foreign, downcall) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + arg_shuffle.print_on(&ls); + } +#endif + + assert(_abi._shadow_space_bytes == frame::z_abi_160_size, "expected space according to ABI"); + int allocated_frame_size = _abi._shadow_space_bytes; + allocated_frame_size += arg_shuffle.out_arg_bytes(); + + assert(!_needs_return_buffer, "unexpected needs_return_buffer"); + RegSpiller out_reg_spiller(_output_registers); + int spill_offset = allocated_frame_size; + allocated_frame_size += BytesPerWord; + + StubLocations locs; + locs.set(StubLocations::TARGET_ADDRESS, _abi._scratch2); + + if (_captured_state_mask != 0) { + __ block_comment("{ _captured_state_mask is set"); + locs.set_frame_data(StubLocations::CAPTURED_STATE_BUFFER, allocated_frame_size); + allocated_frame_size += BytesPerWord; + __ block_comment("} _captured_state_mask is set"); + } + + allocated_frame_size = align_up(allocated_frame_size, StackAlignmentInBytes); + _frame_size_slots = allocated_frame_size >> LogBytesPerInt; + + _oop_maps = _needs_transition ? new OopMapSet() : nullptr; + address start = __ pc(); + + __ save_return_pc(); + __ push_frame(allocated_frame_size, Z_R11); // Create a new frame for the wrapper. + + _frame_complete = __ pc() - start; // frame build complete. + + if (_needs_transition) { + __ block_comment("{ thread java2native"); + __ get_PC(Z_R1_scratch); + address the_pc = __ pc(); + __ set_last_Java_frame(Z_SP, Z_R1_scratch); + + OopMap* map = new OopMap(_frame_size_slots, 0); + _oop_maps->add_gc_map(the_pc - start, map); + + // State transition + __ set_thread_state(_thread_in_native); + __ block_comment("} thread java2native"); + } + __ block_comment("{ argument shuffle"); + arg_shuffle.generate(_masm, shuffle_reg, frame::z_jit_out_preserve_size, _abi._shadow_space_bytes, locs); + __ block_comment("} argument shuffle"); + + __ call(as_Register(locs.get(StubLocations::TARGET_ADDRESS))); + + ////////////////////////////////////////////////////////////////////////////// + + if (_captured_state_mask != 0) { + __ block_comment("{ save thread local"); + + out_reg_spiller.generate_spill(_masm, spill_offset); + + __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, DowncallLinker::capture_state)); + __ z_lg(Z_ARG1, Address(Z_SP, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER))); + __ load_const_optimized(Z_ARG2, _captured_state_mask); + __ call(call_target_address); + + out_reg_spiller.generate_fill(_masm, spill_offset); + + __ block_comment("} save thread local"); + } + + ////////////////////////////////////////////////////////////////////////////// + + Label L_after_safepoint_poll; + Label L_safepoint_poll_slow_path; + Label L_reguard; + Label L_after_reguard; + + if (_needs_transition) { + __ block_comment("{ thread native2java"); + __ set_thread_state(_thread_in_native_trans); + + if (!UseSystemMemoryBarrier) { + __ z_fence(); // Order state change wrt. safepoint poll. + } + + __ safepoint_poll(L_safepoint_poll_slow_path, tmp); + + __ load_and_test_int(tmp, Address(Z_thread, JavaThread::suspend_flags_offset())); + __ z_brne(L_safepoint_poll_slow_path); + + __ bind(L_after_safepoint_poll); + + // change thread state + __ set_thread_state(_thread_in_Java); + + __ block_comment("reguard stack check"); + __ z_cli(Address(Z_thread, JavaThread::stack_guard_state_offset() + in_ByteSize(sizeof(StackOverflow::StackGuardState) - 1)), + StackOverflow::stack_guard_yellow_reserved_disabled); + __ z_bre(L_reguard); + __ bind(L_after_reguard); + + __ reset_last_Java_frame(); + __ block_comment("} thread native2java"); + } + + __ pop_frame(); + __ restore_return_pc(); // This is the way back to the caller. + __ z_br(Z_R14); + + ////////////////////////////////////////////////////////////////////////////// + + if (_needs_transition) { + __ block_comment("{ L_safepoint_poll_slow_path"); + __ bind(L_safepoint_poll_slow_path); + + // Need to save the native result registers around any runtime calls. + out_reg_spiller.generate_spill(_masm, spill_offset); + + __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, JavaThread::check_special_condition_for_native_trans)); + __ z_lgr(Z_ARG1, Z_thread); + __ call(call_target_address); + + out_reg_spiller.generate_fill(_masm, spill_offset); + + __ z_bru(L_after_safepoint_poll); + __ block_comment("} L_safepoint_poll_slow_path"); + + ////////////////////////////////////////////////////////////////////////////// + __ block_comment("{ L_reguard"); + __ bind(L_reguard); + + // Need to save the native result registers around any runtime calls. + out_reg_spiller.generate_spill(_masm, spill_offset); + + __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, SharedRuntime::reguard_yellow_pages)); + __ call(call_target_address); + + out_reg_spiller.generate_fill(_masm, spill_offset); + + __ z_bru(L_after_reguard); + + __ block_comment("} L_reguard"); + } + + ////////////////////////////////////////////////////////////////////////////// + + __ flush(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/foreignGlobals_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/foreignGlobals_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/foreignGlobals_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/foreignGlobals_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -23,34 +23,209 @@ */ #include "precompiled.hpp" -#include "code/vmreg.hpp" +#include "asm/macroAssembler.inline.hpp" +#include "code/vmreg.inline.hpp" +#include "runtime/jniHandles.hpp" +#include "runtime/jniHandles.inline.hpp" +#include "oops/typeArrayOop.inline.hpp" +#include "oops/oopCast.inline.hpp" #include "prims/foreignGlobals.hpp" -#include "utilities/debug.hpp" +#include "prims/foreignGlobals.inline.hpp" +#include "prims/vmstorage.hpp" +#include "utilities/formatBuffer.hpp" -class MacroAssembler; +#define __ masm-> + +bool ABIDescriptor::is_volatile_reg(Register reg) const { + return _integer_volatile_registers.contains(reg); +} + +bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const { + return _float_argument_registers.contains(reg) + || _float_additional_volatile_registers.contains(reg); +} bool ForeignGlobals::is_foreign_linker_supported() { - return false; + return true; } const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { - Unimplemented(); - return {}; + oop abi_oop = JNIHandles::resolve_non_null(jabi); + ABIDescriptor abi; + + objArrayOop inputStorage = jdk_internal_foreign_abi_ABIDescriptor::inputStorage(abi_oop); + parse_register_array(inputStorage, StorageType::INTEGER, abi._integer_argument_registers, as_Register); + parse_register_array(inputStorage, StorageType::FLOAT, abi._float_argument_registers, as_FloatRegister); + + objArrayOop outputStorage = jdk_internal_foreign_abi_ABIDescriptor::outputStorage(abi_oop); + parse_register_array(outputStorage, StorageType::INTEGER, abi._integer_return_registers, as_Register); + parse_register_array(outputStorage, StorageType::FLOAT, abi._float_return_registers, as_FloatRegister); + + objArrayOop volatileStorage = jdk_internal_foreign_abi_ABIDescriptor::volatileStorage(abi_oop); + parse_register_array(volatileStorage, StorageType::INTEGER, abi._integer_volatile_registers, as_Register); + parse_register_array(volatileStorage, StorageType::FLOAT, abi._float_additional_volatile_registers, as_FloatRegister); + + abi._stack_alignment_bytes = jdk_internal_foreign_abi_ABIDescriptor::stackAlignment(abi_oop); + abi._shadow_space_bytes = jdk_internal_foreign_abi_ABIDescriptor::shadowSpace(abi_oop); + + abi._scratch1 = parse_vmstorage(jdk_internal_foreign_abi_ABIDescriptor::scratch1(abi_oop)); + abi._scratch2 = parse_vmstorage(jdk_internal_foreign_abi_ABIDescriptor::scratch2(abi_oop)); + + return abi; } int RegSpiller::pd_reg_size(VMStorage reg) { - Unimplemented(); - return -1; + if (reg.type() == StorageType::INTEGER || reg.type() == StorageType::FLOAT) { + return 8; + } + return 0; // stack and BAD } void RegSpiller::pd_store_reg(MacroAssembler* masm, int offset, VMStorage reg) { - Unimplemented(); + if (reg.type() == StorageType::INTEGER) { + __ reg2mem_opt(as_Register(reg), Address(Z_SP, offset), true); + } else if (reg.type() == StorageType::FLOAT) { + __ freg2mem_opt(as_FloatRegister(reg), Address(Z_SP, offset), true); + } else { + // stack and BAD + } } void RegSpiller::pd_load_reg(MacroAssembler* masm, int offset, VMStorage reg) { - Unimplemented(); + if (reg.type() == StorageType::INTEGER) { + __ mem2reg_opt(as_Register(reg), Address(Z_SP, offset), true); + } else if (reg.type() == StorageType::FLOAT) { + __ mem2freg_opt(as_FloatRegister(reg), Address(Z_SP, offset), true); + } else { + // stack and BAD + } +} + +static int reg2offset(VMStorage vms, int stk_bias) { + assert(!vms.is_reg(), "wrong usage"); + return vms.index_or_offset() + stk_bias; +} + +static void move_reg(MacroAssembler* masm, int out_stk_bias, + VMStorage from_reg, VMStorage to_reg) { + int out_bias = 0; + switch (to_reg.type()) { + case StorageType::INTEGER: + if (to_reg.segment_mask() == REG64_MASK && from_reg.segment_mask() == REG32_MASK ) { + // see CCallingConventionRequiresIntsAsLongs + __ z_lgfr(as_Register(to_reg), as_Register(from_reg)); + } else { + __ lgr_if_needed(as_Register(to_reg), as_Register(from_reg)); + } + break; + case StorageType::STACK: + out_bias = out_stk_bias; //fallthrough + case StorageType::FRAME_DATA: { + // Integer types always get a 64 bit slot in C. + if (from_reg.segment_mask() == REG32_MASK) { + // see CCallingConventionRequiresIntsAsLongs + __ z_lgfr(as_Register(from_reg), as_Register(from_reg)); + } + switch (to_reg.stack_size()) { + case 8: __ reg2mem_opt(as_Register(from_reg), Address(Z_SP, reg2offset(to_reg, out_bias)), true); break; + case 4: __ reg2mem_opt(as_Register(from_reg), Address(Z_SP, reg2offset(to_reg, out_bias)), false); break; + default: ShouldNotReachHere(); + } + } break; + default: ShouldNotReachHere(); + } +} + +static void move_float(MacroAssembler* masm, int out_stk_bias, + VMStorage from_reg, VMStorage to_reg) { + switch (to_reg.type()) { + case StorageType::FLOAT: + if (from_reg.segment_mask() == REG64_MASK) + __ move_freg_if_needed(as_FloatRegister(to_reg), T_DOUBLE, as_FloatRegister(from_reg), T_DOUBLE); + else + __ move_freg_if_needed(as_FloatRegister(to_reg), T_FLOAT, as_FloatRegister(from_reg), T_FLOAT); + break; + case StorageType::STACK: + if (from_reg.segment_mask() == REG64_MASK) { + assert(to_reg.stack_size() == 8, "size should match"); + __ freg2mem_opt(as_FloatRegister(from_reg), Address(Z_SP, reg2offset(to_reg, out_stk_bias)), true); + } else { + assert(to_reg.stack_size() == 4, "size should match"); + __ freg2mem_opt(as_FloatRegister(from_reg), Address(Z_SP, reg2offset(to_reg, out_stk_bias)), false); + } + break; + default: ShouldNotReachHere(); + } +} + +static void move_stack(MacroAssembler* masm, Register tmp_reg, int in_stk_bias, int out_stk_bias, + VMStorage from_reg, VMStorage to_reg) { + int out_bias = 0; + Address from_addr(Z_R11, reg2offset(from_reg, in_stk_bias)); + switch (to_reg.type()) { + case StorageType::INTEGER: + switch (from_reg.stack_size()) { + case 8: __ mem2reg_opt(as_Register(to_reg), from_addr, true);break; + case 4: __ mem2reg_opt(as_Register(to_reg), from_addr, false);break; + default: ShouldNotReachHere(); + } + break; + case StorageType::FLOAT: + switch (from_reg.stack_size()) { + case 8: __ mem2freg_opt(as_FloatRegister(to_reg), from_addr, true);break; + case 4: __ mem2freg_opt(as_FloatRegister(to_reg), from_addr, false);break; + default: ShouldNotReachHere(); + } + break; + case StorageType::STACK: + out_bias = out_stk_bias; // fallthrough + case StorageType::FRAME_DATA: { + switch (from_reg.stack_size()) { + case 8: __ mem2reg_opt(tmp_reg, from_addr, true); break; + case 4: if (to_reg.stack_size() == 8) { + __ mem2reg_signed_opt(tmp_reg, from_addr); + } else { + __ mem2reg_opt(tmp_reg, from_addr, false); + } + break; + default: ShouldNotReachHere(); + } + switch (to_reg.stack_size()) { + case 8: __ reg2mem_opt(tmp_reg, Address (Z_SP, reg2offset(to_reg, out_bias)), true); break; + case 4: __ reg2mem_opt(tmp_reg, Address (Z_SP, reg2offset(to_reg, out_bias)), false); break; + default: ShouldNotReachHere(); + } + } break; + default: ShouldNotReachHere(); + } } void ArgumentShuffle::pd_generate(MacroAssembler* masm, VMStorage tmp, int in_stk_bias, int out_stk_bias, const StubLocations& locs) const { - Unimplemented(); + Register tmp_reg = as_Register(tmp); + for (int i = 0; i < _moves.length(); i++) { + Move move = _moves.at(i); + VMStorage from_reg = move.from; + VMStorage to_reg = move.to; + + // replace any placeholders + if (from_reg.type() == StorageType::PLACEHOLDER) { + from_reg = locs.get(from_reg); + } + if (to_reg.type() == StorageType::PLACEHOLDER) { + to_reg = locs.get(to_reg); + } + + switch (from_reg.type()) { + case StorageType::INTEGER: + move_reg(masm, out_stk_bias, from_reg, to_reg); + break; + case StorageType::FLOAT: + move_float(masm, out_stk_bias, from_reg, to_reg); + break; + case StorageType::STACK: + move_stack(masm, tmp_reg, in_stk_bias, out_stk_bias, from_reg, to_reg); + break; + default: ShouldNotReachHere(); + } + } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/foreignGlobals_s390.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/foreignGlobals_s390.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/foreignGlobals_s390.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/foreignGlobals_s390.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -24,6 +24,23 @@ #ifndef CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP #define CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP -class ABIDescriptor {}; +struct ABIDescriptor { + GrowableArray _integer_argument_registers; + GrowableArray _integer_return_registers; + GrowableArray _float_argument_registers; + GrowableArray _float_return_registers; + + GrowableArray _integer_volatile_registers; + GrowableArray _float_additional_volatile_registers; + + int32_t _stack_alignment_bytes; + int32_t _shadow_space_bytes; + + VMStorage _scratch1; + VMStorage _scratch2; + + bool is_volatile_reg(Register reg) const; + bool is_volatile_reg(FloatRegister reg) const; +}; #endif // CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/frame_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/frame_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/frame_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/frame_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -218,13 +218,32 @@ } UpcallStub::FrameData* UpcallStub::frame_data_for_frame(const frame& frame) const { - ShouldNotCallThis(); - return nullptr; + assert(frame.is_upcall_stub_frame(), "wrong frame"); + // need unextended_sp here, since normal sp is wrong for interpreter callees + return reinterpret_cast( + reinterpret_cast
(frame.unextended_sp()) + in_bytes(_frame_data_offset)); } bool frame::upcall_stub_frame_is_first() const { - ShouldNotCallThis(); - return false; + assert(is_upcall_stub_frame(), "must be optimized entry frame"); + UpcallStub* blob = _cb->as_upcall_stub(); + JavaFrameAnchor* jfa = blob->jfa_for_frame(*this); + return jfa->last_Java_sp() == nullptr; +} + +frame frame::sender_for_upcall_stub_frame(RegisterMap* map) const { + assert(map != nullptr, "map must be set"); + UpcallStub* blob = _cb->as_upcall_stub(); + // Java frame called from C; skip all C frames and return top C + // frame of that chunk as the sender + JavaFrameAnchor* jfa = blob->jfa_for_frame(*this); + assert(!upcall_stub_frame_is_first(), "must have a frame anchor to go back to"); + assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); + map->clear(); + assert(map->include_argument_oops(), "should be set by clear"); + frame fr(jfa->last_Java_sp(), jfa->last_Java_pc()); + + return fr; } frame frame::sender_for_interpreter_frame(RegisterMap *map) const { @@ -653,7 +672,6 @@ return fp(); } -// Pointer beyond the "oldest/deepest" BasicObjectLock on stack. BasicObjectLock* frame::interpreter_frame_monitor_end() const { return interpreter_frame_monitors(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/frame_s390.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/frame_s390.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/frame_s390.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/frame_s390.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -488,11 +488,6 @@ template static void update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr); - // Additional interface for interpreter frames: - static int interpreter_frame_interpreterstate_size_in_bytes(); - static int interpreter_frame_monitor_size_in_bytes(); - - // template interpreter state inline z_ijava_state* ijava_state_unchecked() const; diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/frame_s390.inline.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/frame_s390.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/frame_s390.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/frame_s390.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -254,15 +254,6 @@ WordsPerLong /* Number of stack slots for a Java long. */); } -inline int frame::interpreter_frame_monitor_size_in_bytes() { - // Number of bytes for a monitor. - return frame::interpreter_frame_monitor_size() * wordSize; -} - -inline int frame::interpreter_frame_interpreterstate_size_in_bytes() { - return z_ijava_state_size; -} - inline Method** frame::interpreter_frame_method_addr() const { return (Method**)&(ijava_state()->method); } @@ -352,12 +343,10 @@ // update it accordingly. map->set_include_argument_oops(false); - if (is_entry_frame()) { - return sender_for_entry_frame(map); - } - if (is_interpreted_frame()) { - return sender_for_interpreter_frame(map); - } + if (is_entry_frame()) return sender_for_entry_frame(map); + if (is_upcall_stub_frame()) return sender_for_upcall_stub_frame(map); + if (is_interpreted_frame()) return sender_for_interpreter_frame(map); + assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); if (_cb != nullptr) return sender_for_compiled_frame(map); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/globalDefinitions_s390.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/globalDefinitions_s390.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/globalDefinitions_s390.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/globalDefinitions_s390.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -28,7 +28,7 @@ #define ShortenBranches true -const int StackAlignmentInBytes = 16; +const int StackAlignmentInBytes = 8; #define SUPPORTS_NATIVE_CX8 diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/interp_masm_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/interp_masm_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/interp_masm_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/interp_masm_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -838,7 +838,7 @@ // Check that all monitors are unlocked. { NearLabel loop, exception, entry, restart; - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); // We use Z_ARG2 so that if we go slow path it will be the correct // register for unlock_object to pass to VM directly. Register R_current_monitor = Z_ARG2; @@ -951,6 +951,11 @@ // Test if reserved zone needs to be enabled. Label no_reserved_zone_enabling; + // check if already enabled - if so no re-enabling needed + assert(sizeof(StackOverflow::StackGuardState) == 4, "unexpected size"); + z_ly(Z_R0, Address(Z_thread, JavaThread::stack_guard_state_offset())); + compare32_and_branch(Z_R0, StackOverflow::stack_guard_enabled, bcondEqual, no_reserved_zone_enabling); + // Compare frame pointers. There is no good stack pointer, as with stack // frame compression we can get different SPs when we do calls. A subsequent // call could have a smaller SP, so that this compare succeeds for an @@ -977,9 +982,10 @@ // lock object // // Registers alive -// monitor - Address of the BasicObjectLock to be used for locking, +// monitor (Z_R10) - Address of the BasicObjectLock to be used for locking, // which must be initialized with the object to lock. -// object - Address of the object to be locked. +// object (Z_R11, Z_R2) - Address of the object to be locked. +// templateTable (monitorenter) is using Z_R2 for object void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { if (LockingMode == LM_MONITOR) { @@ -987,7 +993,7 @@ return; } - // template code: + // template code: (for LM_LEGACY) // // markWord displaced_header = obj->mark().set_unlocked(); // monitor->lock()->set_displaced_header(displaced_header); @@ -1001,68 +1007,77 @@ // InterpreterRuntime::monitorenter(THREAD, monitor); // } - const Register displaced_header = Z_ARG5; + const int hdr_offset = oopDesc::mark_offset_in_bytes(); + + const Register header = Z_ARG5; const Register object_mark_addr = Z_ARG4; const Register current_header = Z_ARG5; + const Register tmp = Z_R1_scratch; - NearLabel done; - NearLabel slow_case; + NearLabel done, slow_case; - // markWord displaced_header = obj->mark().set_unlocked(); + // markWord header = obj->mark().set_unlocked(); - // Load markWord from object into displaced_header. - z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object); + // Load markWord from object into header. + z_lg(header, hdr_offset, object); if (DiagnoseSyncOnValueBasedClasses != 0) { - load_klass(Z_R1_scratch, object); - testbit(Address(Z_R1_scratch, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + load_klass(tmp, object); + testbit(Address(tmp, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); z_btrue(slow_case); } - // Set displaced_header to be (markWord of object | UNLOCK_VALUE). - z_oill(displaced_header, markWord::unlocked_value); + if (LockingMode == LM_LIGHTWEIGHT) { + lightweight_lock(object, /* mark word */ header, tmp, slow_case); + } else if (LockingMode == LM_LEGACY) { - // monitor->lock()->set_displaced_header(displaced_header); + // Set header to be (markWord of object | UNLOCK_VALUE). + // This will not change anything if it was unlocked before. + z_oill(header, markWord::unlocked_value); - // Initialize the box (Must happen before we update the object mark!). - z_stg(displaced_header, in_bytes(BasicObjectLock::lock_offset()) + - BasicLock::displaced_header_offset_in_bytes(), monitor); + // monitor->lock()->set_displaced_header(displaced_header); + const int lock_offset = in_bytes(BasicObjectLock::lock_offset()); + const int mark_offset = lock_offset + BasicLock::displaced_header_offset_in_bytes(); - // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) { + // Initialize the box (Must happen before we update the object mark!). + z_stg(header, mark_offset, monitor); - // Store stack address of the BasicObjectLock (this is monitor) into object. - add2reg(object_mark_addr, oopDesc::mark_offset_in_bytes(), object); + // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) { - z_csg(displaced_header, monitor, 0, object_mark_addr); - assert(current_header==displaced_header, "must be same register"); // Identified two registers from z/Architecture. + // not necessary, use offset in instruction directly. + // add2reg(object_mark_addr, hdr_offset, object); - z_bre(done); + // Store stack address of the BasicObjectLock (this is monitor) into object. + z_csg(header, monitor, hdr_offset, object); + assert(current_header == header, + "must be same register"); // Identified two registers from z/Architecture. - // } else if (THREAD->is_lock_owned((address)displaced_header)) - // // Simple recursive case. - // monitor->lock()->set_displaced_header(nullptr); + z_bre(done); - // We did not see an unlocked object so try the fast recursive case. + // } else if (THREAD->is_lock_owned((address)displaced_header)) + // // Simple recursive case. + // monitor->lock()->set_displaced_header(nullptr); - // Check if owner is self by comparing the value in the markWord of object - // (current_header) with the stack pointer. - z_sgr(current_header, Z_SP); - - assert(os::vm_page_size() > 0xfff, "page size too small - change the constant"); - - // The prior sequence "LGR, NGR, LTGR" can be done better - // (Z_R1 is temp and not used after here). - load_const_optimized(Z_R0, (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); - z_ngr(Z_R0, current_header); // AND sets CC (result eq/ne 0) - - // If condition is true we are done and hence we can store 0 in the displaced - // header indicating it is a recursive lock and be done. - z_brne(slow_case); - z_release(); // Membar unnecessary on zarch AND because the above csg does a sync before and after. - z_stg(Z_R0/*==0!*/, in_bytes(BasicObjectLock::lock_offset()) + - BasicLock::displaced_header_offset_in_bytes(), monitor); - z_bru(done); + // We did not see an unlocked object so try the fast recursive case. + + // Check if owner is self by comparing the value in the markWord of object + // (current_header) with the stack pointer. + z_sgr(current_header, Z_SP); + + assert(os::vm_page_size() > 0xfff, "page size too small - change the constant"); + // The prior sequence "LGR, NGR, LTGR" can be done better + // (Z_R1 is temp and not used after here). + load_const_optimized(Z_R0, (~(os::vm_page_size() - 1) | markWord::lock_mask_in_place)); + z_ngr(Z_R0, current_header); // AND sets CC (result eq/ne 0) + + // If condition is true we are done and hence we can store 0 in the displaced + // header indicating it is a recursive lock and be done. + z_brne(slow_case); + z_release(); // Member unnecessary on zarch AND because the above csg does a sync before and after. + z_stg(Z_R0/*==0!*/, mark_offset, monitor); + } + z_bru(done); // } else { // // Slow path. // InterpreterRuntime::monitorenter(THREAD, monitor); @@ -1070,8 +1085,16 @@ // None of the above fast optimizations worked so we have to get into the // slow case of monitor enter. bind(slow_case); - call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), monitor); - + if (LockingMode == LM_LIGHTWEIGHT) { + // for lightweight locking we need to use monitorenter_obj, see interpreterRuntime.cpp + call_VM(noreg, + CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter_obj), + object); + } else { + call_VM(noreg, + CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), + monitor); + } // } bind(done); @@ -1092,7 +1115,7 @@ } // else { - // template code: + // template code: (for LM_LEGACY): // // if ((displaced_header = monitor->displaced_header()) == nullptr) { // // Recursive unlock. Mark the monitor unlocked by setting the object field to null. @@ -1105,10 +1128,12 @@ // InterpreterRuntime::monitorexit(monitor); // } - const Register displaced_header = Z_ARG4; - const Register current_header = Z_R1; + const int hdr_offset = oopDesc::mark_offset_in_bytes(); + + const Register header = Z_ARG4; + const Register current_header = Z_R1_scratch; Address obj_entry(monitor, BasicObjectLock::obj_offset()); - Label done; + Label done, slow_case; if (object == noreg) { // In the template interpreter, we must assure that the object @@ -1118,35 +1143,63 @@ z_lg(object, obj_entry); } - assert_different_registers(monitor, object, displaced_header, current_header); + assert_different_registers(monitor, object, header, current_header); // 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)); + // monitor->lock()->set_displaced_header(displaced_header); + const int lock_offset = in_bytes(BasicObjectLock::lock_offset()); + const int mark_offset = lock_offset + BasicLock::displaced_header_offset_in_bytes(); - // Test first if we are in the fast recursive case. - MacroAssembler::load_and_test_long(displaced_header, - Address(monitor, in_bytes(BasicObjectLock::lock_offset()) + - BasicLock::displaced_header_offset_in_bytes())); - z_bre(done); // displaced_header == 0 -> goto done + clear_mem(obj_entry, sizeof(oop)); + if (LockingMode != LM_LIGHTWEIGHT) { + // Test first if we are in the fast recursive case. + MacroAssembler::load_and_test_long(header, Address(monitor, mark_offset)); + z_bre(done); // header == 0 -> goto done + } // } 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(nullptr); // If we still have a lightweight lock, unlock the object and be done. + if (LockingMode == LM_LIGHTWEIGHT) { + // Check for non-symmetric locking. This is allowed by the spec and the interpreter + // must handle it. + + Register tmp = current_header; + + // First check for lock-stack underflow. + z_lgf(tmp, Address(Z_thread, JavaThread::lock_stack_top_offset())); + compareU32_and_branch(tmp, (unsigned)LockStack::start_offset(), Assembler::bcondNotHigh, slow_case); + + // Then check if the top of the lock-stack matches the unlocked object. + z_aghi(tmp, -oopSize); + z_lg(tmp, Address(Z_thread, tmp)); + compare64_and_branch(tmp, object, Assembler::bcondNotEqual, slow_case); + + z_lg(header, Address(object, hdr_offset)); + z_lgr(tmp, header); + z_nill(tmp, markWord::monitor_value); + z_brne(slow_case); - // The markword is expected to be at offset 0. - assert(oopDesc::mark_offset_in_bytes() == 0, "unlock_object: review code below"); + lightweight_unlock(object, header, tmp, slow_case); - // We have the displaced header in displaced_header. If the lock is still - // lightweight, it will contain the monitor address and we'll store the - // displaced header back into the object's mark word. - z_lgr(current_header, monitor); - z_csg(current_header, displaced_header, 0, object); - z_bre(done); + z_bru(done); + } else { + // The markword is expected to be at offset 0. + // This is not required on s390, at least not here. + assert(hdr_offset == 0, "unlock_object: review code below"); + + // We have the displaced header in header. If the lock is still + // lightweight, it will contain the monitor address and we'll store the + // displaced header back into the object's mark word. + z_lgr(current_header, monitor); + z_csg(current_header, header, hdr_offset, object); + z_bre(done); + } // } else { // // Slow path. @@ -1154,6 +1207,7 @@ // The lock has been converted into a heavy lock and hence // we need to get into the slow case. + bind(slow_case); z_stg(object, obj_entry); // Restore object entry, has been cleared above. call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor); @@ -2033,7 +2087,7 @@ const Register Rcurr_slot = Rtemp1; const Register Rlimit = Rtemp2; - const jint delta = -frame::interpreter_frame_monitor_size() * wordSize; + const jint delta = -frame::interpreter_frame_monitor_size_in_bytes(); assert((delta & LongAlignmentMask) == 0, "sizeof BasicObjectLock must be even number of doublewords"); @@ -2214,6 +2268,6 @@ void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { if (VerifyFPU) { - unimplemented("verfiyFPU"); + unimplemented("verifyFPU"); } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/macroAssembler_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/macroAssembler_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/macroAssembler_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/macroAssembler_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3165,11 +3165,15 @@ // Handle existing monitor. // The object has an existing monitor iff (mark & monitor_value) != 0. guarantee(Immediate::is_uimm16(markWord::monitor_value), "must be half-word"); - z_lr(temp, displacedHeader); + z_lgr(temp, displacedHeader); z_nill(temp, markWord::monitor_value); z_brne(object_has_monitor); - if (LockingMode != LM_MONITOR) { + if (LockingMode == LM_MONITOR) { + // Set NE to indicate 'failure' -> take slow-path + z_ltgr(oop, oop); + z_bru(done); + } else if (LockingMode == LM_LEGACY) { // Set mark to markWord | markWord::unlocked_value. z_oill(displacedHeader, markWord::unlocked_value); @@ -3186,23 +3190,23 @@ z_csg(displacedHeader, box, 0, oop); assert(currentHeader == displacedHeader, "must be same register"); // Identified two registers from z/Architecture. z_bre(done); - } else { - // Set NE to indicate 'failure' -> take slow-path - z_ltgr(oop, oop); - z_bru(done); - } - // We did not see an unlocked object so try the fast recursive case. + // We did not see an unlocked object so try the fast recursive case. - z_sgr(currentHeader, Z_SP); - load_const_optimized(temp, (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); + z_sgr(currentHeader, Z_SP); + load_const_optimized(temp, (~(os::vm_page_size() - 1) | markWord::lock_mask_in_place)); - z_ngr(currentHeader, temp); - // z_brne(done); - // z_release(); - z_stg(currentHeader/*==0 or not 0*/, BasicLock::displaced_header_offset_in_bytes(), box); + z_ngr(currentHeader, temp); + // z_brne(done); + // z_release(); + z_stg(currentHeader/*==0 or not 0*/, BasicLock::displaced_header_offset_in_bytes(), box); - z_bru(done); + z_bru(done); + } else { + assert(LockingMode == LM_LIGHTWEIGHT, "must be"); + lightweight_lock(oop, displacedHeader, temp, done); + z_bru(done); + } Register zero = temp; Register monitor_tagged = displacedHeader; // Tagged with markWord::monitor_value. @@ -3214,8 +3218,10 @@ 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); - // Store a non-null value into the box. - z_stg(box, BasicLock::displaced_header_offset_in_bytes(), box); + if (LockingMode != LM_LIGHTWEIGHT) { + // Store a non-null value into the box. + z_stg(box, BasicLock::displaced_header_offset_in_bytes(), box); + } #ifdef ASSERT z_brne(done); // We've acquired the monitor, check some invariants. @@ -3238,11 +3244,13 @@ Register temp = temp1; Register monitor = temp2; + const int hdr_offset = oopDesc::mark_offset_in_bytes(); + Label done, object_has_monitor; BLOCK_COMMENT("compiler_fast_unlock_object {"); - if (LockingMode != LM_MONITOR) { + if (LockingMode == LM_LEGACY) { // Find the lock address and load the displaced header from the stack. // if the displaced header is zero, we have a recursive unlock. load_and_test_long(displacedHeader, Address(box, BasicLock::displaced_header_offset_in_bytes())); @@ -3251,27 +3259,41 @@ // Handle existing monitor. // The object has an existing monitor iff (mark & monitor_value) != 0. - z_lg(currentHeader, oopDesc::mark_offset_in_bytes(), oop); + z_lg(currentHeader, hdr_offset, oop); guarantee(Immediate::is_uimm16(markWord::monitor_value), "must be half-word"); + if (LockingMode == LM_LIGHTWEIGHT) { + z_lgr(temp, currentHeader); + } z_nill(currentHeader, markWord::monitor_value); z_brne(object_has_monitor); - if (LockingMode != LM_MONITOR) { + if (LockingMode == LM_MONITOR) { + // Set NE to indicate 'failure' -> take slow-path + z_ltgr(oop, oop); + z_bru(done); + } else if (LockingMode == LM_LEGACY) { // Check if it is still a light weight lock, this is true if we see // the stack address of the basicLock in the markWord of the object // copy box to currentHeader such that csg does not kill it. z_lgr(currentHeader, box); z_csg(currentHeader, displacedHeader, 0, oop); - z_bru(done); // Csg sets CR as desired. + z_bru(done); // csg sets CR as desired. } else { - // Set NE to indicate 'failure' -> take slow-path - z_ltgr(oop, oop); + assert(LockingMode == LM_LIGHTWEIGHT, "must be"); + + // don't load currentHead again from stack-top after monitor check, as it is possible + // some other thread modified it. + // currentHeader is altered, but it's contents are copied in temp as well + lightweight_unlock(oop, temp, currentHeader, done); z_bru(done); } + // In case of LM_LIGHTWEIGHT, we may reach here with (temp & ObjectMonitor::ANONYMOUS_OWNER) != 0. + // This is handled like owner thread mismatches: We take the slow path. + // Handle existing monitor. bind(object_has_monitor); - z_lg(currentHeader, oopDesc::mark_offset_in_bytes(), oop); // CurrentHeader is tagged with monitor_value set. + z_lg(currentHeader, hdr_offset, oop); // CurrentHeader is tagged with monitor_value set. load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions))); z_brne(done); load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner))); @@ -5621,3 +5643,103 @@ SkipIfEqual::~SkipIfEqual() { _masm->bind(_label); } + +// Implements lightweight-locking. +// Branches to slow upon failure to lock the object. +// Falls through upon success. +// +// - obj: the object to be locked, contents preserved. +// - hdr: the header, already loaded from obj, contents destroyed. +// Note: make sure Z_R1 is not manipulated here when C2 compiler is in play +void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register temp, Label& slow_case) { + + assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); + assert_different_registers(obj, hdr, temp); + + // First we need to check if the lock-stack has room for pushing the object reference. + z_lgf(temp, Address(Z_thread, JavaThread::lock_stack_top_offset())); + + compareU32_and_branch(temp, (unsigned)LockStack::end_offset()-1, bcondHigh, slow_case); + + // attempting a lightweight_lock + // Load (object->mark() | 1) into hdr + z_oill(hdr, markWord::unlocked_value); + + z_lgr(temp, hdr); + + // Clear lock-bits from hdr (locked state) + z_xilf(temp, markWord::unlocked_value); + + z_csg(hdr, temp, oopDesc::mark_offset_in_bytes(), obj); + branch_optimized(Assembler::bcondNotEqual, slow_case); + + // After successful lock, push object on lock-stack + z_lgf(temp, Address(Z_thread, JavaThread::lock_stack_top_offset())); + z_stg(obj, Address(Z_thread, temp)); + z_ahi(temp, oopSize); + z_st(temp, Address(Z_thread, JavaThread::lock_stack_top_offset())); + + // as locking was successful, set CC to EQ + z_cr(temp, temp); +} + +// Implements lightweight-unlocking. +// Branches to slow upon failure. +// Falls through upon success. +// +// - obj: the object to be unlocked +// - hdr: the (pre-loaded) header of the object, will be destroyed +// - Z_R1_scratch: will be killed in case of Interpreter & C1 Compiler +void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Register tmp, Label& slow) { + + assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking"); + assert_different_registers(obj, hdr, tmp); + +#ifdef ASSERT + { + // Check that hdr is lightweight-locked. + Label hdr_ok; + z_lgr(tmp, hdr); + z_nill(tmp, markWord::lock_mask_in_place); + z_bre(hdr_ok); + stop("Header is not lightweight-locked"); + bind(hdr_ok); + } + { + // The following checks rely on the fact that LockStack is only ever modified by + // its owning thread, even if the lock got inflated concurrently; removal of LockStack + // entries after inflation will happen delayed in that case. + + // Check for lock-stack underflow. + Label stack_ok; + z_lgf(tmp, Address(Z_thread, JavaThread::lock_stack_top_offset())); + compareU32_and_branch(tmp, (unsigned)LockStack::start_offset(), Assembler::bcondHigh, stack_ok); + stop("Lock-stack underflow"); + bind(stack_ok); + } + { + // Check if the top of the lock-stack matches the unlocked object. + Label tos_ok; + z_aghi(tmp, -oopSize); + z_lg(tmp, Address(Z_thread, tmp)); + compare64_and_branch(tmp, obj, Assembler::bcondEqual, tos_ok); + stop("Top of lock-stack does not match the unlocked object"); + bind(tos_ok); + } +#endif // ASSERT + + z_lgr(tmp, hdr); + z_oill(tmp, markWord::unlocked_value); + z_csg(hdr, tmp, oopDesc::mark_offset_in_bytes(), obj); + branch_optimized(Assembler::bcondNotEqual, slow); + + // After successful unlock, pop object from lock-stack +#ifdef ASSERT + z_lgf(tmp, Address(Z_thread, JavaThread::lock_stack_top_offset())); + z_aghi(tmp, -oopSize); + z_agr(tmp, Z_thread); + z_xc(0, oopSize-1, tmp, 0, tmp); // wipe out lock-stack entry +#endif + z_alsi(in_bytes(JavaThread::lock_stack_top_offset()), Z_thread, -oopSize); // pop object + z_cr(tmp, tmp); // set CC to EQ +} diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/macroAssembler_s390.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/macroAssembler_s390.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/macroAssembler_s390.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/macroAssembler_s390.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -722,6 +722,8 @@ void compiler_fast_lock_object(Register oop, Register box, Register temp1, Register temp2); void compiler_fast_unlock_object(Register oop, Register box, Register temp1, Register temp2); + void lightweight_lock(Register obj, Register hdr, Register tmp, Label& slow); + void lightweight_unlock(Register obj, Register hdr, Register tmp, Label& slow); void resolve_jobject(Register value, Register tmp1, Register tmp2); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/methodHandles_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/methodHandles_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/methodHandles_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/methodHandles_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -349,7 +349,16 @@ void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_reg, Register temp_target) { BLOCK_COMMENT("jump_to_native_invoker {"); - __ should_not_reach_here(); + assert(nep_reg != noreg, "required register"); + + // Load the invoker, as NEP -> .invoker + __ verify_oop(nep_reg); + + __ z_lg(temp_target, Address(nep_reg, + NONZERO(jdk_internal_foreign_abi_NativeEntryPoint::downcall_stub_address_offset_in_bytes()))); + + __ z_br(temp_target); + BLOCK_COMMENT("} jump_to_native_invoker"); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/sharedRuntime_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/sharedRuntime_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/sharedRuntime_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/sharedRuntime_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1716,7 +1716,9 @@ __ add2reg(r_box, lock_offset, Z_SP); // Try fastpath for locking. - // Fast_lock kills r_temp_1, r_temp_2. (Don't use R1 as temp, won't work!) + // Fast_lock kills r_temp_1, r_temp_2. + // in case of DiagnoseSyncOnValueBasedClasses content for Z_R1_scratch + // will be destroyed, So avoid using Z_R1 as temp here. __ compiler_fast_lock_object(r_oop, r_box, r_tmp1, r_tmp2); __ z_bre(done); @@ -1915,7 +1917,8 @@ __ add2reg(r_box, lock_offset, Z_SP); // Try fastpath for unlocking. - __ compiler_fast_unlock_object(r_oop, r_box, r_tmp1, r_tmp2); // Don't use R1 as temp. + // Fast_unlock kills r_tmp1, r_tmp2. + __ compiler_fast_unlock_object(r_oop, r_box, r_tmp1, r_tmp2); __ z_bre(done); // Slow path for unlocking. diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/templateTable_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/templateTable_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/templateTable_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/templateTable_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -4143,7 +4143,7 @@ // Check for null object. __ null_check(Z_tos); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); NearLabel allocated; // Initialize entry pointer. const Register Rfree_slot = Z_tmp_1; @@ -4238,7 +4238,7 @@ // Find matching slot. { - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); NearLabel entry, loop; const Register Rbot = Z_ARG3; // Points to word under bottom of monitor block. diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/upcallLinker_s390.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/upcallLinker_s390.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/upcallLinker_s390.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/upcallLinker_s390.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -22,15 +22,287 @@ */ #include "precompiled.hpp" +#include "asm/macroAssembler.inline.hpp" +#include "logging/logStream.hpp" +#include "memory/resourceArea.hpp" #include "prims/upcallLinker.hpp" -#include "utilities/debug.hpp" +#include "runtime/sharedRuntime.hpp" +#include "runtime/signature.hpp" +#include "runtime/stubRoutines.hpp" +#include "utilities/formatBuffer.hpp" +#include "utilities/globalDefinitions.hpp" +#define __ _masm-> + +// for callee saved regs, according to the caller's ABI +static int compute_reg_save_area_size(const ABIDescriptor& abi) { + int size = 0; + for (int i = 0; i < Register::number_of_registers; i++) { + Register reg = as_Register(i); + // Z_SP saved/restored by prologue/epilogue + if (reg == Z_SP) continue; + if (!abi.is_volatile_reg(reg)) { + size += 8; // bytes + } + } + + for (int i = 0; i < FloatRegister::number_of_registers; i++) { + FloatRegister reg = as_FloatRegister(i); + if (!abi.is_volatile_reg(reg)) { + size += 8; // bytes + } + } + + return size; +} + +static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { + // 1. iterate all registers in the architecture + // - check if they are volatile or not for the given abi + // - if NOT, we need to save it here + + int offset = reg_save_area_offset; + + __ block_comment("{ preserve_callee_saved_regs "); + for (int i = 0; i < Register::number_of_registers; i++) { + Register reg = as_Register(i); + // Z_SP saved/restored by prologue/epilogue + if (reg == Z_SP) continue; + if (!abi.is_volatile_reg(reg)) { + __ z_stg(reg, Address(Z_SP, offset)); + offset += 8; + } + } + + for (int i = 0; i < FloatRegister::number_of_registers; i++) { + FloatRegister reg = as_FloatRegister(i); + if (!abi.is_volatile_reg(reg)) { + __ z_std(reg, Address(Z_SP, offset)); + offset += 8; + } + } + + __ block_comment("} preserve_callee_saved_regs "); +} + +static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { + // 1. iterate all registers in the architecture + // - check if they are volatile or not for the given abi + // - if NOT, we need to restore it here + + int offset = reg_save_area_offset; + + __ block_comment("{ restore_callee_saved_regs "); + for (int i = 0; i < Register::number_of_registers; i++) { + Register reg = as_Register(i); + // Z_SP saved/restored by prologue/epilogue + if (reg == Z_SP) continue; + if (!abi.is_volatile_reg(reg)) { + __ z_lg(reg, Address(Z_SP, offset)); + offset += 8; + } + } + + for (int i = 0; i < FloatRegister::number_of_registers; i++) { + FloatRegister reg = as_FloatRegister(i); + if (!abi.is_volatile_reg(reg)) { + __ z_ld(reg, Address(Z_SP, offset)); + offset += 8; + } + } + + __ block_comment("} restore_callee_saved_regs "); +} + +static const int upcall_stub_code_base_size = 1024; // depends on GC (resolve_jobject) +static const int upcall_stub_size_per_arg = 16; // arg save & restore + move address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, BasicType* in_sig_bt, int total_in_args, BasicType* out_sig_bt, int total_out_args, BasicType ret_type, jobject jabi, jobject jconv, bool needs_return_buffer, int ret_buf_size) { - ShouldNotCallThis(); - return nullptr; + ResourceMark rm; + const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi); + const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); + int code_size = upcall_stub_code_base_size + (total_in_args * upcall_stub_size_per_arg); + CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 0); + + Register call_target_address = Z_R1_scratch; + + VMStorage shuffle_reg = abi._scratch1; + JavaCallingConvention out_conv; + NativeCallingConvention in_conv(call_regs._arg_regs); + ArgumentShuffle arg_shuffle(in_sig_bt, total_in_args, out_sig_bt, total_out_args, &in_conv, &out_conv, shuffle_reg); + + // The Java call uses the JIT ABI, but we also call C. + int out_arg_area = MAX2(frame::z_jit_out_preserve_size + arg_shuffle.out_arg_bytes(), (int)frame::z_abi_160_size); + +#ifndef PRODUCT + LogTarget(Trace, foreign, upcall) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + arg_shuffle.print_on(&ls); + } +#endif + + + int reg_save_area_size = compute_reg_save_area_size(abi); + RegSpiller arg_spiller(call_regs._arg_regs); + RegSpiller result_spiller(call_regs._ret_regs); + + int res_save_area_offset = out_arg_area; + int arg_save_area_offset = res_save_area_offset + result_spiller.spill_size_bytes(); + int reg_save_area_offset = arg_save_area_offset + arg_spiller.spill_size_bytes(); + int frame_data_offset = reg_save_area_offset + reg_save_area_size; + int frame_bottom_offset = frame_data_offset + sizeof(UpcallStub::FrameData); + + int frame_size = align_up(frame_bottom_offset, StackAlignmentInBytes); + StubLocations locs; + + // The space we have allocated will look like: + // + // + // FP-> | | + // |---------------------| = frame_bottom_offset = frame_size + // | | + // | FrameData | + // |---------------------| = frame_data_offset + // | | + // | reg_save_area | + // |---------------------| = reg_save_are_offset + // | | + // | arg_save_area | + // |---------------------| = arg_save_are_offset + // | | + // | res_save_area | + // |---------------------| = res_save_are_offset + // | | + // SP-> | out_arg_area | needs to be at end for shadow space + // + // + + ////////////////////////////////////////////////////////////////////////////// + + MacroAssembler* _masm = new MacroAssembler(&buffer); + address start = __ pc(); + + __ save_return_pc(); + assert((abi._stack_alignment_bytes % StackAlignmentInBytes) == 0, "must be 8 byte aligned"); + // allocate frame (frame_size is also aligned, so stack is still aligned) + __ push_frame(frame_size); + + // we have to always spill args since we need to do a call to get the thread + // (and maybe attach it). + arg_spiller.generate_spill(_masm, arg_save_area_offset); + // Java methods won't preserve them, so save them here: + preserve_callee_saved_registers(_masm, abi, reg_save_area_offset); + + __ block_comment("{ on_entry"); + __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry)); + __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); + __ call(call_target_address); + __ z_lgr(Z_thread, Z_RET); + __ block_comment("} on_entry"); + + arg_spiller.generate_fill(_masm, arg_save_area_offset); + __ block_comment("{ argument shuffle"); + arg_shuffle.generate(_masm, shuffle_reg, abi._shadow_space_bytes, frame::z_jit_out_preserve_size, locs); + __ block_comment("} argument shuffle"); + + __ block_comment("{ receiver "); + __ load_const_optimized(Z_ARG1, (intptr_t)receiver); + __ resolve_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2); + __ block_comment("} receiver "); + + __ load_const_optimized(Z_method, (intptr_t)entry); + __ z_stg(Z_method, Address(Z_thread, in_bytes(JavaThread::callee_target_offset()))); + + __ z_lg(call_target_address, Address(Z_method, in_bytes(Method::from_compiled_offset()))); + __ call(call_target_address); + + // return value shuffle + assert(!needs_return_buffer, "unexpected needs_return_buffer"); + // CallArranger can pick a return type that goes in the same reg for both CCs. + if (call_regs._ret_regs.length() > 0) { // 0 or 1 + VMStorage ret_reg = call_regs._ret_regs.at(0); + // Check if the return reg is as expected. + switch (ret_type) { + case T_BOOLEAN: + case T_BYTE: + case T_SHORT: + case T_CHAR: + case T_INT: + __ z_lgfr(Z_RET, Z_RET); // Clear garbage in high half. + // fallthrough + case T_LONG: + assert(as_Register(ret_reg) == Z_RET, "unexpected result register"); + break; + case T_FLOAT: + case T_DOUBLE: + assert(as_FloatRegister(ret_reg) == Z_FRET, "unexpected result register"); + break; + default: + fatal("unexpected return type: %s", type2name(ret_type)); + } + } + + result_spiller.generate_spill(_masm, res_save_area_offset); + + __ block_comment("{ on_exit"); + __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_exit)); + __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); + __ call(call_target_address); + __ block_comment("} on_exit"); + + restore_callee_saved_registers(_masm, abi, reg_save_area_offset); + + result_spiller.generate_fill(_masm, res_save_area_offset); + + __ pop_frame(); + __ restore_return_pc(); + __ z_br(Z_R14); + + ////////////////////////////////////////////////////////////////////////////// + + __ block_comment("{ exception handler"); + + intptr_t exception_handler_offset = __ pc() - start; + + // Native caller has no idea how to handle exceptions, + // so we just crash here. Up to callee to catch exceptions. + __ verify_oop(Z_ARG1); + __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception)); + __ call_c(call_target_address); + __ should_not_reach_here(); + + __ block_comment("} exception handler"); + + _masm->flush(); + +#ifndef PRODUCT + stringStream ss; + ss.print("upcall_stub_%s", entry->signature()->as_C_string()); + const char* name = _masm->code_string(ss.as_string()); +#else // PRODUCT + const char* name = "upcall_stub"; +#endif // PRODUCT + + buffer.log_section_sizes(name); + UpcallStub* blob + = UpcallStub::create(name, + &buffer, + exception_handler_offset, + receiver, + in_ByteSize(frame_data_offset)); +#ifndef PRODUCT + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + blob->print_on(&ls); + } +#endif + + return blob->code_begin(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/s390/vmstorage_s390.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/s390/vmstorage_s390.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/s390/vmstorage_s390.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/s390/vmstorage_s390.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -29,24 +29,79 @@ #include "asm/register.hpp" enum class StorageType : int8_t { - STACK = 0, - PLACEHOLDER = 1, -// special locations used only by native code - FRAME_DATA = PLACEHOLDER + 1, + INTEGER = 0, + FLOAT = 1, + STACK = 2, + PLACEHOLDER = 3, + // special locations used only by native code + FRAME_DATA = 4, INVALID = -1 }; // need to define this before constructing VMStorage (below) constexpr inline bool VMStorage::is_reg(StorageType type) { - return false; + return type == StorageType::INTEGER || type == StorageType::FLOAT; } constexpr inline StorageType VMStorage::stack_type() { return StorageType::STACK; } constexpr inline StorageType VMStorage::placeholder_type() { return StorageType::PLACEHOLDER; } constexpr inline StorageType VMStorage::frame_data_type() { return StorageType::FRAME_DATA; } +// Needs to be consistent with S390Architecture.java. +constexpr uint16_t REG32_MASK = 0b0000000000000001; +constexpr uint16_t REG64_MASK = 0b0000000000000011; + +inline Register as_Register(VMStorage vms) { + assert(vms.type() == StorageType::INTEGER, "not the right type"); + return ::as_Register(vms.index()); +} + +inline FloatRegister as_FloatRegister(VMStorage vms) { + assert(vms.type() == StorageType::FLOAT, "not the right type"); + return ::as_FloatRegister(vms.index()); +} + +inline VMStorage as_VMStorage(Register reg, uint16_t segment_mask = REG64_MASK) { + return VMStorage::reg_storage(StorageType::INTEGER, segment_mask, reg->encoding()); +} + +inline VMStorage as_VMStorage(FloatRegister reg, uint16_t segment_mask = REG64_MASK) { + return VMStorage::reg_storage(StorageType::FLOAT, segment_mask, reg->encoding()); +} + inline VMStorage as_VMStorage(VMReg reg, BasicType bt) { + if (reg->is_Register()) { + uint16_t segment_mask = 0; + switch (bt) { + case T_BOOLEAN: + case T_CHAR : + case T_BYTE : + case T_SHORT : + case T_INT : segment_mask = REG32_MASK; break; + default : segment_mask = REG64_MASK; break; + } + return as_VMStorage(reg->as_Register(), segment_mask); + } else if (reg->is_FloatRegister()) { + // FP regs always use double format. However, we need the correct format for loads /stores. + return as_VMStorage(reg->as_FloatRegister(), (bt == T_FLOAT) ? REG32_MASK : REG64_MASK); + } else if (reg->is_stack()) { + uint16_t size = 0; + switch (bt) { + case T_BOOLEAN: + case T_CHAR : + case T_BYTE : + case T_SHORT : + case T_INT : + case T_FLOAT : size = 4; break; + default : size = 8; break; + } + return VMStorage(StorageType::STACK, size, + checked_cast(reg->reg2stack() * VMRegImpl::stack_slot_size)); + } else if (!reg->is_valid()) { + return VMStorage::invalid(); + } + ShouldNotReachHere(); return VMStorage::invalid(); } -#endif // CPU_S390_VMSTORAGE_S390_INLINE_HPP \ No newline at end of file +#endif // CPU_S390_VMSTORAGE_S390_INLINE_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1713,7 +1713,7 @@ assert_different_registers(obj, k_RInfo, klass_RInfo); - __ cmpptr(obj, NULL_WORD); + __ testptr(obj, obj); if (op->should_profile()) { Label not_null; __ jccb(Assembler::notEqual, not_null); @@ -1792,7 +1792,7 @@ __ pop(klass_RInfo); __ pop(klass_RInfo); // result is a boolean - __ cmpl(klass_RInfo, 0); + __ testl(klass_RInfo, klass_RInfo); __ jcc(Assembler::equal, *failure_target); // successful cast, fall through to profile or jump } @@ -1806,7 +1806,7 @@ __ pop(klass_RInfo); __ pop(k_RInfo); // result is a boolean - __ cmpl(k_RInfo, 0); + __ testl(k_RInfo, k_RInfo); __ jcc(Assembler::equal, *failure_target); // successful cast, fall through to profile or jump } @@ -1859,7 +1859,7 @@ Label *success_target = op->should_profile() ? &profile_cast_success : &done; Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); - __ cmpptr(value, NULL_WORD); + __ testptr(value, value); if (op->should_profile()) { Label not_null; __ jccb(Assembler::notEqual, not_null); @@ -1890,7 +1890,7 @@ __ pop(klass_RInfo); __ pop(k_RInfo); // result is a boolean - __ cmpl(k_RInfo, 0); + __ testl(k_RInfo, k_RInfo); __ jcc(Assembler::equal, *failure_target); // fall through to the success case @@ -2047,7 +2047,7 @@ } else { Label skip; - __ jcc (acond, skip); + __ jccb(acond, skip); if (opr2->is_cpu_register()) { reg2reg(opr2, result); } else if (opr2->is_stack()) { @@ -2664,13 +2664,18 @@ // cpu register - constant LIR_Const* c = opr2->as_constant_ptr(); if (c->type() == T_INT) { - __ cmpl(reg1, c->as_jint()); + jint i = c->as_jint(); + if (i == 0) { + __ testl(reg1, reg1); + } else { + __ cmpl(reg1, i); + } } else if (c->type() == T_METADATA) { // All we need for now is a comparison with null for equality. assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops"); Metadata* m = c->as_metadata(); if (m == nullptr) { - __ cmpptr(reg1, NULL_WORD); + __ testptr(reg1, reg1); } else { ShouldNotReachHere(); } @@ -2678,7 +2683,7 @@ // In 64bit oops are single register jobject o = c->as_jobject(); if (o == nullptr) { - __ cmpptr(reg1, NULL_WORD); + __ testptr(reg1, reg1); } else { __ cmpoop(reg1, o, rscratch1); } @@ -3146,7 +3151,7 @@ #endif // _LP64 - __ cmpl(rax, 0); + __ testl(rax, rax); __ jcc(Assembler::equal, *stub->continuation()); __ mov(tmp, rax); @@ -3288,7 +3293,7 @@ __ pop(dst); __ pop(src); - __ cmpl(src, 0); + __ testl(src, src); __ jcc(Assembler::notEqual, cont); __ bind(slow); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -69,7 +69,7 @@ const Register thread = disp_hdr; get_thread(thread); #endif - fast_lock_impl(obj, hdr, thread, tmp, slow_case); + lightweight_lock(obj, hdr, thread, tmp, slow_case); } else if (LockingMode == LM_LEGACY) { Label done; // and mark it as unlocked @@ -135,7 +135,7 @@ if (LockingMode == LM_LIGHTWEIGHT) { movptr(disp_hdr, Address(obj, hdr_offset)); andptr(disp_hdr, ~(int32_t)markWord::lock_mask_in_place); - fast_unlock_impl(obj, disp_hdr, hdr, slow_case); + lightweight_unlock(obj, disp_hdr, hdr, slow_case); } else if (LockingMode == LM_LEGACY) { // test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object - if the object header is not pointing to diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -621,7 +621,7 @@ movptr(Address(boxReg, 0), tmpReg); } else { assert(LockingMode == LM_LIGHTWEIGHT, ""); - fast_lock_impl(objReg, tmpReg, thread, scrReg, NO_COUNT); + lightweight_lock(objReg, tmpReg, thread, scrReg, NO_COUNT); jmp(COUNT); } jmp(DONE_LABEL); @@ -925,7 +925,7 @@ bind (Stacked); if (LockingMode == LM_LIGHTWEIGHT) { mov(boxReg, tmpReg); - fast_unlock_impl(objReg, boxReg, tmpReg, NO_COUNT); + lightweight_unlock(objReg, boxReg, tmpReg, NO_COUNT); jmp(COUNT); } else if (LockingMode == LM_LEGACY) { movptr(tmpReg, Address (boxReg, 0)); // re-fetch diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/interp_masm_x86.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/interp_masm_x86.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/interp_masm_x86.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/interp_masm_x86.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1074,7 +1074,7 @@ // Check that all monitors are unlocked { Label loop, exception, entry, restart; - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); const Address monitor_block_top( rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( @@ -1150,6 +1150,8 @@ NOT_LP64(get_thread(rthread);) + // check if already enabled - if so no re-enabling needed + assert(sizeof(StackOverflow::StackGuardState) == 4, "unexpected size"); cmpl(Address(rthread, JavaThread::stack_guard_state_offset()), StackOverflow::stack_guard_enabled); jcc(Assembler::equal, no_reserved_zone_enabling); @@ -1232,7 +1234,7 @@ #endif // Load object header, prepare for CAS from unlocked to locked. movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - fast_lock_impl(obj_reg, swap_reg, thread, tmp_reg, slow_case); + lightweight_lock(obj_reg, swap_reg, thread, tmp_reg, slow_case); } else if (LockingMode == LM_LEGACY) { // Load immediate 1 into swap_reg %rax movl(swap_reg, 1); @@ -1362,7 +1364,7 @@ // Try to swing header from locked to unlocked. movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); andptr(swap_reg, ~(int32_t)markWord::lock_mask_in_place); - fast_unlock_impl(obj_reg, swap_reg, header_reg, slow_case); + lightweight_unlock(obj_reg, swap_reg, header_reg, slow_case); } else if (LockingMode == LM_LEGACY) { // Load the old header from BasicLock structure movptr(header_reg, Address(swap_reg, diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/macroAssembler_x86.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/macroAssembler_x86.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -9801,7 +9801,7 @@ bind(L_stack_ok); } -// Implements fast-locking. +// Implements lightweight-locking. // Branches to slow upon failure to lock the object, with ZF cleared. // Falls through upon success with unspecified ZF. // @@ -9809,7 +9809,7 @@ // hdr: the (pre-loaded) header of the object, must be rax // thread: the thread which attempts to lock obj // tmp: a temporary register -void MacroAssembler::fast_lock_impl(Register obj, Register hdr, Register thread, Register tmp, Label& slow) { +void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register thread, Register tmp, Label& slow) { assert(hdr == rax, "header must be in rax for cmpxchg"); assert_different_registers(obj, hdr, thread, tmp); @@ -9837,14 +9837,14 @@ movl(Address(thread, JavaThread::lock_stack_top_offset()), tmp); } -// Implements fast-unlocking. +// Implements lightweight-unlocking. // Branches to slow upon failure, with ZF cleared. // Falls through upon success, with unspecified ZF. // // obj: the object to be unlocked // hdr: the (pre-loaded) header of the object, must be rax // tmp: a temporary register -void MacroAssembler::fast_unlock_impl(Register obj, Register hdr, Register tmp, Label& slow) { +void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Register tmp, Label& slow) { assert(hdr == rax, "header must be in rax for cmpxchg"); assert_different_registers(obj, hdr, tmp); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/macroAssembler_x86.hpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/macroAssembler_x86.hpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -2022,8 +2022,8 @@ void check_stack_alignment(Register sp, const char* msg, unsigned bias = 0, Register tmp = noreg); - void fast_lock_impl(Register obj, Register hdr, Register thread, Register tmp, Label& slow); - void fast_unlock_impl(Register obj, Register hdr, Register tmp, Label& slow); + void lightweight_lock(Register obj, Register hdr, Register thread, Register tmp, Label& slow); + void lightweight_unlock(Register obj, Register hdr, Register tmp, Label& slow); }; /** diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1717,7 +1717,7 @@ assert(LockingMode == LM_LIGHTWEIGHT, "must be"); // Load object header __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ fast_lock_impl(obj_reg, swap_reg, thread, lock_reg, slow_path_lock); + __ lightweight_lock(obj_reg, swap_reg, thread, lock_reg, slow_path_lock); } __ bind(count_mon); __ inc_held_monitor_count(); @@ -1876,7 +1876,7 @@ assert(LockingMode == LM_LIGHTWEIGHT, "must be"); __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); __ andptr(swap_reg, ~(int32_t)markWord::lock_mask_in_place); - __ fast_unlock_impl(obj_reg, swap_reg, lock_reg, slow_path_unlock); + __ lightweight_unlock(obj_reg, swap_reg, lock_reg, slow_path_unlock); __ dec_held_monitor_count(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2187,7 +2187,7 @@ assert(LockingMode == LM_LIGHTWEIGHT, "must be"); // Load object header __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ fast_lock_impl(obj_reg, swap_reg, r15_thread, rscratch1, slow_path_lock); + __ lightweight_lock(obj_reg, swap_reg, r15_thread, rscratch1, slow_path_lock); } __ bind(count_mon); __ inc_held_monitor_count(); @@ -2331,7 +2331,7 @@ assert(LockingMode == LM_LIGHTWEIGHT, "must be"); __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); __ andptr(swap_reg, ~(int32_t)markWord::lock_mask_in_place); - __ fast_unlock_impl(obj_reg, swap_reg, lock_reg, slow_path_unlock); + __ lightweight_unlock(obj_reg, swap_reg, lock_reg, slow_path_unlock); __ dec_held_monitor_count(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -477,7 +477,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(void) { // monitor entry size: see picture of stack in frame_x86.hpp - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); // total overhead size: entry_size + (saved rbp through expr stack // bottom). be sure to change this if you add/subtract anything @@ -566,7 +566,7 @@ const Address monitor_block_top( rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); #ifdef ASSERT { diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/templateTable_x86.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/x86/templateTable_x86.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/templateTable_x86.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/templateTable_x86.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -4319,7 +4319,7 @@ rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( rbp, frame::interpreter_frame_initial_sp_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); Label allocated; @@ -4416,7 +4416,7 @@ rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( rbp, frame::interpreter_frame_initial_sp_offset * wordSize); - const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); Register rtop = LP64_ONLY(c_rarg1) NOT_LP64(rdx); Register rbot = LP64_ONLY(c_rarg2) NOT_LP64(rbx); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/x86/x86.ad openjdk-21-21.0.2+13/src/hotspot/cpu/x86/x86.ad --- openjdk-21-21.0.1+12/src/hotspot/cpu/x86/x86.ad 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/x86/x86.ad 2024-01-16 16:19:00.000000000 +0000 @@ -8985,9 +8985,9 @@ %} -instruct vmask_gen(kReg dst, rRegL len, rRegL temp) %{ +instruct vmask_gen(kReg dst, rRegL len, rRegL temp, rFlagsReg cr) %{ match(Set dst (VectorMaskGen len)); - effect(TEMP temp); + effect(TEMP temp, KILL cr); format %{ "vector_mask_gen32 $dst, $len \t! vector mask generator" %} ins_encode %{ __ genmask($dst$$KRegister, $len$$Register, $temp$$Register); diff -Nru openjdk-21-21.0.1+12/src/hotspot/cpu/zero/frame_zero.cpp openjdk-21-21.0.2+13/src/hotspot/cpu/zero/frame_zero.cpp --- openjdk-21-21.0.1+12/src/hotspot/cpu/zero/frame_zero.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/cpu/zero/frame_zero.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -82,7 +82,6 @@ return get_interpreterState()->monitor_base(); } -// Pointer beyond the "oldest/deepest" BasicObjectLock on stack. BasicObjectLock* frame::interpreter_frame_monitor_end() const { return (BasicObjectLock*) get_interpreterState()->stack_base(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/os/aix/libodm_aix.cpp openjdk-21-21.0.2+13/src/hotspot/os/aix/libodm_aix.cpp --- openjdk-21-21.0.1+12/src/hotspot/os/aix/libodm_aix.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os/aix/libodm_aix.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -29,13 +29,16 @@ #include #include #include "runtime/arguments.hpp" +#include "runtime/os.hpp" dynamicOdm::dynamicOdm() { - const char *libodmname = "/usr/lib/libodm.a(shr_64.o)"; - _libhandle = dlopen(libodmname, RTLD_MEMBER | RTLD_NOW); + const char* libodmname = "/usr/lib/libodm.a(shr_64.o)"; + char ebuf[512]; + void* _libhandle = os::dll_load(libodmname, ebuf, sizeof(ebuf)); + if (!_libhandle) { - trcVerbose("Couldn't open %s", libodmname); + trcVerbose("Cannot load %s (error %s)", libodmname, ebuf); return; } _odm_initialize = (fun_odm_initialize )dlsym(_libhandle, "odm_initialize" ); diff -Nru openjdk-21-21.0.1+12/src/hotspot/os/aix/libperfstat_aix.cpp openjdk-21-21.0.2+13/src/hotspot/os/aix/libperfstat_aix.cpp --- openjdk-21-21.0.1+12/src/hotspot/os/aix/libperfstat_aix.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os/aix/libperfstat_aix.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -26,6 +26,7 @@ #include "libperfstat_aix.hpp" #include "misc_aix.hpp" +#include "runtime/os.hpp" #include @@ -71,11 +72,11 @@ static fun_wpar_getcid_t g_fun_wpar_getcid = nullptr; bool libperfstat::init() { - - // Dynamically load the libperfstat porting library. - g_libhandle = dlopen("/usr/lib/libperfstat.a(shr_64.o)", RTLD_MEMBER | RTLD_NOW); + const char* libperfstat = "/usr/lib/libperfstat.a(shr_64.o)"; + char ebuf[512]; + g_libhandle = os::dll_load(libperfstat, ebuf, sizeof(ebuf)); if (!g_libhandle) { - trcVerbose("Cannot load libperfstat.a (dlerror: %s)", dlerror()); + trcVerbose("Cannot load %s (error: %s)", libperfstat, ebuf); return false; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/os/aix/loadlib_aix.cpp openjdk-21-21.0.2+13/src/hotspot/os/aix/loadlib_aix.cpp --- openjdk-21-21.0.1+12/src/hotspot/os/aix/loadlib_aix.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os/aix/loadlib_aix.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -225,6 +225,7 @@ lm->path = g_stringlist.add(ldi->ldinfo_filename); if (!lm->path) { trcVerbose("OOM."); + free(lm); goto cleanup; } @@ -246,6 +247,7 @@ lm->member = g_stringlist.add(p_mbr_name); if (!lm->member) { trcVerbose("OOM."); + free(lm); goto cleanup; } } else { diff -Nru openjdk-21-21.0.1+12/src/hotspot/os/aix/os_aix.cpp openjdk-21-21.0.2+13/src/hotspot/os/aix/os_aix.cpp --- openjdk-21-21.0.1+12/src/hotspot/os/aix/os_aix.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os/aix/os_aix.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1098,8 +1098,6 @@ return true; } -// Loads .dll/.so and in case of error it checks if .dll/.so was built -// for the same architecture as Hotspot is running on. void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { log_info(os)("attempting shared library load of %s", filename); @@ -1114,8 +1112,17 @@ return nullptr; } - // RTLD_LAZY is currently not implemented. The dl is loaded immediately with all its dependants. - void * result= ::dlopen(filename, RTLD_LAZY); + // RTLD_LAZY has currently the same behavior as RTLD_NOW + // The dl is loaded immediately with all its dependants. + int dflags = RTLD_LAZY; + // check for filename ending with ')', it indicates we want to load + // a MEMBER module that is a member of an archive. + int flen = strlen(filename); + if (flen > 0 && filename[flen - 1] == ')') { + dflags |= RTLD_MEMBER; + } + + void * result= ::dlopen(filename, dflags); if (result != nullptr) { Events::log_dll_message(nullptr, "Loaded shared library %s", filename); // Reload dll cache. Don't do this in signal handling. @@ -3009,3 +3016,32 @@ void os::jfr_report_memory_info() {} #endif // INCLUDE_JFR + +// Simulate the library search algorithm of dlopen() (in os::dll_load) +int os::Aix::stat64x_via_LIBPATH(const char* path, struct stat64x* stat) { + if (path[0] == '/' || + (path[0] == '.' && (path[1] == '/' || + (path[1] == '.' && path[2] == '/')))) { + return stat64x(path, stat); + } + + const char* env = getenv("LIBPATH"); + if (env == nullptr || *env == 0) + return -1; + + int ret = -1; + size_t libpathlen = strlen(env); + char* libpath = NEW_C_HEAP_ARRAY(char, libpathlen + 1, mtServiceability); + char* combined = NEW_C_HEAP_ARRAY(char, libpathlen + strlen(path) + 1, mtServiceability); + char *saveptr, *token; + strcpy(libpath, env); + for (token = strtok_r(libpath, ":", &saveptr); token != nullptr; token = strtok_r(nullptr, ":", &saveptr)) { + sprintf(combined, "%s/%s", token, path); + if (0 == (ret = stat64x(combined, stat))) + break; + } + + FREE_C_HEAP_ARRAY(char*, combined); + FREE_C_HEAP_ARRAY(char*, libpath); + return ret; +} diff -Nru openjdk-21-21.0.1+12/src/hotspot/os/aix/os_aix.hpp openjdk-21-21.0.2+13/src/hotspot/os/aix/os_aix.hpp --- openjdk-21-21.0.1+12/src/hotspot/os/aix/os_aix.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os/aix/os_aix.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, 2016 SAP SE. All rights reserved. + * Copyright (c) 2013, 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 @@ -174,6 +174,9 @@ static bool platform_print_native_stack(outputStream* st, const void* context, char *buf, int buf_size, address& lastpc); static void* resolve_function_descriptor(void* p); + + // Simulate the library search algorithm of dlopen() (in os::dll_load) + static int stat64x_via_LIBPATH(const char* path, struct stat64x* stat); }; #endif // OS_AIX_OS_AIX_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/os/linux/os_linux.cpp openjdk-21-21.0.2+13/src/hotspot/os/linux/os_linux.cpp --- openjdk-21-21.0.1+12/src/hotspot/os/linux/os_linux.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os/linux/os_linux.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3802,15 +3802,17 @@ return; } - // 2) check if large pages are configured - if ( ( UseTransparentHugePages && HugePages::supports_thp() == false) || - (!UseTransparentHugePages && HugePages::supports_static_hugepages() == false) ) { - // No large pages configured, return. + // 2) check if the OS supports THPs resp. static hugepages. + if (UseTransparentHugePages && !HugePages::supports_thp()) { + if (!FLAG_IS_DEFAULT(UseTransparentHugePages)) { + log_warning(pagesize)("UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system."); + } + UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false; + return; + } + if (!UseTransparentHugePages && !HugePages::supports_static_hugepages()) { warn_no_large_pages_configured(); - UseLargePages = false; - UseTransparentHugePages = false; - UseHugeTLBFS = false; - UseSHM = false; + UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false; return; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp --- openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -33,10 +33,23 @@ // Note that memory_order_conservative requires a full barrier after atomic stores. // See https://patchwork.kernel.org/patch/3575821/ +#if defined(__clang_major__) +#define FULL_COMPILER_ATOMIC_SUPPORT +#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ >= 2)) +#define FULL_COMPILER_ATOMIC_SUPPORT +#endif + template struct Atomic::PlatformAdd { template D add_then_fetch(D volatile* dest, I add_value, atomic_memory_order order) const { + +#ifndef FULL_COMPILER_ATOMIC_SUPPORT + // If we add add and fetch for sub word and are using older compiler + // it must be added here due to not using lib atomic. + STATIC_ASSERT(byte_size >= 4); +#endif + if (order != memory_order_relaxed) { FULL_MEM_BARRIER; } @@ -55,12 +68,65 @@ } }; +#ifndef FULL_COMPILER_ATOMIC_SUPPORT +template<> +template +inline T Atomic::PlatformCmpxchg<1>::operator()(T volatile* dest __attribute__((unused)), + T compare_value, + T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(1 == sizeof(T)); + + if (order != memory_order_relaxed) { + FULL_MEM_BARRIER; + } + + uint32_t volatile* aligned_dst = (uint32_t volatile*)(((uintptr_t)dest) & (~((uintptr_t)0x3))); + int shift = 8 * (((uintptr_t)dest) - ((uintptr_t)aligned_dst)); // 0, 8, 16, 24 + + uint64_t mask = 0xfful << shift; // 0x00000000..FF.. + uint64_t remask = ~mask; // 0xFFFFFFFF..00.. + + uint64_t w_cv = ((uint64_t)(unsigned char)compare_value) << shift; // widen to 64-bit 0x00000000..CC.. + uint64_t w_ev = ((uint64_t)(unsigned char)exchange_value) << shift; // widen to 64-bit 0x00000000..EE.. + + uint64_t old_value; + uint64_t rc_temp; + + __asm__ __volatile__ ( + "1: lr.w %0, %2 \n\t" + " and %1, %0, %5 \n\t" // ignore unrelated bytes and widen to 64-bit 0x00000000..XX.. + " bne %1, %3, 2f \n\t" // compare 64-bit w_cv + " and %1, %0, %6 \n\t" // remove old byte + " or %1, %1, %4 \n\t" // add new byte + " sc.w %1, %1, %2 \n\t" // store new word + " bnez %1, 1b \n\t" + "2: \n\t" + : /*%0*/"=&r" (old_value), /*%1*/"=&r" (rc_temp), /*%2*/"+A" (*aligned_dst) + : /*%3*/"r" (w_cv), /*%4*/"r" (w_ev), /*%5*/"r" (mask), /*%6*/"r" (remask) + : "memory" ); + + if (order != memory_order_relaxed) { + FULL_MEM_BARRIER; + } + + return (T)((old_value & mask) >> shift); +} +#endif + template template inline T Atomic::PlatformXchg::operator()(T volatile* dest, T exchange_value, atomic_memory_order order) const { +#ifndef FULL_COMPILER_ATOMIC_SUPPORT + // If we add xchg for sub word and are using older compiler + // it must be added here due to not using lib atomic. + STATIC_ASSERT(byte_size >= 4); +#endif + STATIC_ASSERT(byte_size == sizeof(T)); + if (order != memory_order_relaxed) { FULL_MEM_BARRIER; } @@ -80,6 +146,11 @@ T compare_value, T exchange_value, atomic_memory_order order) const { + +#ifndef FULL_COMPILER_ATOMIC_SUPPORT + STATIC_ASSERT(byte_size >= 4); +#endif + STATIC_ASSERT(byte_size == sizeof(T)); T value = compare_value; if (order != memory_order_relaxed) { @@ -148,4 +219,6 @@ void operator()(volatile T* p, T v) const { release_store(p, v); OrderAccess::fence(); } }; +#undef FULL_COMPILER_ATOMIC_SUPPORT + #endif // OS_CPU_LINUX_RISCV_ATOMIC_LINUX_RISCV_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp --- openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -37,7 +37,7 @@ inline void OrderAccess::loadstore() { acquire(); } inline void OrderAccess::storeload() { fence(); } -#define FULL_MEM_BARRIER __sync_synchronize() +#define FULL_MEM_BARRIER __atomic_thread_fence(__ATOMIC_SEQ_CST); #define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); #define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); diff -Nru openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp --- openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -45,6 +45,10 @@ #define RISCV_HWPROBE_KEY_IMA_EXT_0 4 #define RISCV_HWPROBE_IMA_FD (1 << 0) #define RISCV_HWPROBE_IMA_C (1 << 1) +#define RISCV_HWPROBE_IMA_V (1 << 2) +#define RISCV_HWPROBE_EXT_ZBA (1 << 3) +#define RISCV_HWPROBE_EXT_ZBB (1 << 4) +#define RISCV_HWPROBE_EXT_ZBS (1 << 5) #define RISCV_HWPROBE_KEY_CPUPERF_0 5 #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0) @@ -100,7 +104,7 @@ static bool is_set(int64_t key, uint64_t value_mask) { if (is_valid(key)) { - return query[key].value & value_mask != 0; + return (query[key].value & value_mask) != 0; } return false; } @@ -129,6 +133,18 @@ if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_IMA_C)) { VM_Version::ext_C.enable_feature(); } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_IMA_V)) { + VM_Version::ext_V.enable_feature(); + } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBA)) { + VM_Version::ext_Zba.enable_feature(); + } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBB)) { + VM_Version::ext_Zbb.enable_feature(); + } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBS)) { + VM_Version::ext_Zbs.enable_feature(); + } if (is_valid(RISCV_HWPROBE_KEY_CPUPERF_0)) { VM_Version::unaligned_access.enable_feature( query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK); diff -Nru openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp --- openjdk-21-21.0.1+12/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -149,12 +149,21 @@ void VM_Version::os_aux_features() { uint64_t auxv = getauxval(AT_HWCAP); - int i = 0; - while (_feature_list[i] != nullptr) { + for (int i = 0; _feature_list[i] != nullptr; i++) { + if (_feature_list[i]->feature_bit() == HWCAP_ISA_V) { + // Special case for V: some dev boards only support RVV version 0.7, while + // the OpenJDK only supports RVV version 1.0. These two versions are not + // compatible with each other. Given the V bit is set through HWCAP on + // some custom kernels, regardless of the version, it can lead to + // generating V instructions on boards that don't support RVV version 1.0 + // (ex: Sipeed LicheePi), leading to a SIGILL. + // That is an acceptable workaround as only Linux Kernel v6.5+ supports V, + // and that version already support hwprobe anyway + continue; + } if ((_feature_list[i]->feature_bit() & auxv) != 0) { _feature_list[i]->enable_feature(); } - i++; } } @@ -224,19 +233,11 @@ void VM_Version::rivos_features() { // Enable common features not dependent on marchid/mimpid. - ext_I.enable_feature(); - ext_M.enable_feature(); - ext_A.enable_feature(); - ext_F.enable_feature(); - ext_D.enable_feature(); - ext_C.enable_feature(); - ext_H.enable_feature(); - ext_V.enable_feature(); - ext_Zicbom.enable_feature(); ext_Zicboz.enable_feature(); ext_Zicbop.enable_feature(); + // If we running on a pre-6.5 kernel ext_Zba.enable_feature(); ext_Zbb.enable_feature(); ext_Zbs.enable_feature(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/adlc/output_c.cpp openjdk-21-21.0.2+13/src/hotspot/share/adlc/output_c.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/adlc/output_c.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/adlc/output_c.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3124,6 +3124,9 @@ fprintf(fp_cpp, " if( i != cisc_operand() ) \n"); fprintf(fp_cpp, " to[i] = _opnds[i]->clone();\n"); fprintf(fp_cpp, " }\n"); + fprintf(fp_cpp, " // Do not increment node index counter, since node reuses my index\n"); + fprintf(fp_cpp, " Compile* C = Compile::current();\n"); + fprintf(fp_cpp, " C->set_unique(C->unique() - 1);\n"); fprintf(fp_cpp, "}\n"); } fprintf(fp_cpp, "\n"); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/c1/c1_LIRGenerator.cpp openjdk-21-21.0.2+13/src/hotspot/share/c1/c1_LIRGenerator.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/c1/c1_LIRGenerator.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/c1/c1_LIRGenerator.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -78,6 +78,7 @@ PhiResolver::PhiResolver(LIRGenerator* gen) : _gen(gen) , _state(gen->resolver_state()) + , _loop(nullptr) , _temp(LIR_OprFact::illegalOpr) { // reinitialize the shared state arrays diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/c1/c1_RangeCheckElimination.cpp openjdk-21-21.0.2+13/src/hotspot/share/c1/c1_RangeCheckElimination.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/c1/c1_RangeCheckElimination.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/c1/c1_RangeCheckElimination.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -404,8 +404,11 @@ aii->_max = idx; aii->_list = new AccessIndexedList(); } else if (idx >= aii->_min && idx <= aii->_max) { - remove_range_check(ai); - return; + // Guard against underflow/overflow (see 'range_cond' check in RangeCheckEliminator::in_block_motion) + if (aii->_max < 0 || (aii->_max + min_jint) <= aii->_min) { + remove_range_check(ai); + return; + } } aii->_min = MIN2(aii->_min, idx); aii->_max = MAX2(aii->_max, idx); @@ -448,9 +451,9 @@ } } } else { - int last_integer = 0; + jint last_integer = 0; Instruction *last_instruction = index; - int base = 0; + jint base = 0; ArithmeticOp *ao = index->as_ArithmeticOp(); while (ao != nullptr && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) { @@ -462,12 +465,12 @@ } if (c) { - int value = c->type()->as_IntConstant()->value(); + jint value = c->type()->as_IntConstant()->value(); if (value != min_jint) { if (ao->op() == Bytecodes::_isub) { value = -value; } - base += value; + base = java_add(base, value); last_integer = base; last_instruction = other; } @@ -489,12 +492,12 @@ assert(info != nullptr, "Info must not be null"); // if idx < 0, max > 0, max + idx may fall between 0 and - // length-1 and if min < 0, min + idx may overflow and be >= + // length-1 and if min < 0, min + idx may underflow/overflow and be >= // 0. The predicate wouldn't trigger but some accesses could // be with a negative index. This test guarantees that for the // min and max value that are kept the predicate can't let // some incorrect accesses happen. - bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min); + bool range_cond = (info->_max < 0 || (info->_max + min_jint) <= info->_min); // Generate code only if more than 2 range checks can be eliminated because of that. // 2 because at least 2 comparisons are done @@ -843,7 +846,7 @@ ); remove_range_check(ai); - } else if (_optimistic && loop_header) { + } else if (false && _optimistic && loop_header) { assert(ai->array(), "Array must not be null!"); assert(ai->index(), "Index must not be null!"); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/c1/c1_ValueMap.cpp openjdk-21-21.0.2+13/src/hotspot/share/c1/c1_ValueMap.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/c1/c1_ValueMap.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/c1/c1_ValueMap.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -359,6 +359,33 @@ } } +class CheckInsertionPoint : public ValueVisitor { + private: + Value _insert; + bool _valid = true; + + void visit(Value* vp) { + assert(*vp != nullptr, "value should not be null"); + if (_insert->dominator_depth() < (*vp)->dominator_depth()) { + _valid = false; + } + } + + public: + bool is_valid() { return _valid; } + CheckInsertionPoint(Value insert) + : _insert(insert) { + assert(insert != nullptr, "insertion point should not be null"); + } +}; + +// Check that insertion point has higher dom depth than all inputs to cur +static bool is_dominated_by_inputs(Instruction* insertion_point, Instruction* cur) { + CheckInsertionPoint v(insertion_point); + cur->input_values_do(&v); + return v.is_valid(); +} + void LoopInvariantCodeMotion::process_block(BlockBegin* block) { TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id())); @@ -394,7 +421,7 @@ cur_invariant = is_invariant(cvt->value()); } - if (cur_invariant) { + if (cur_invariant && is_dominated_by_inputs(_insertion_point, cur)) { // perform value numbering and mark instruction as loop-invariant _gvn->substitute(cur); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/cds/filemap.cpp openjdk-21-21.0.2+13/src/hotspot/share/cds/filemap.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/cds/filemap.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/cds/filemap.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -368,7 +368,7 @@ _from_class_path_attr = ent->_from_class_path_attr; set_name(ent->name(), CHECK); - if (ent->is_jar() && !ent->is_signed() && ent->manifest() != nullptr) { + if (ent->is_jar() && ent->manifest() != nullptr) { Array* buf = MetadataFactory::new_array(loader_data, ent->manifest_size(), CHECK); @@ -622,29 +622,6 @@ buf[len] = 0; return buf; } - - // The return value indicates if the JAR is signed or not - bool check_is_signed() { - u1* attr = _current; - bool isSigned = false; - while (_current < _buffer_end) { - if (*_current == '\n') { - *_current = '\0'; - u1* value = (u1*)strchr((char*)attr, ':'); - if (value != nullptr) { - assert(*(value+1) == ' ', "Unrecognized format" ); - if (strstr((char*)attr, "-Digest") != nullptr) { - isSigned = true; - break; - } - } - *_current = '\n'; // restore - attr = _current + 1; - } - _current ++; - } - return isSigned; - } }; void FileMapInfo::update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) { @@ -657,18 +634,14 @@ if (manifest != nullptr) { ManifestStream* stream = new ManifestStream((u1*)manifest, manifest_size); - if (stream->check_is_signed()) { - ent->set_is_signed(); - } else { - // Copy the manifest into the shared archive - manifest = ClassLoaderExt::read_raw_manifest(THREAD, cpe, &manifest_size); - Array* buf = MetadataFactory::new_array(loader_data, - manifest_size, - CHECK); - char* p = (char*)(buf->data()); - memcpy(p, manifest, manifest_size); - ent->set_manifest(buf); - } + // Copy the manifest into the shared archive + manifest = ClassLoaderExt::read_raw_manifest(THREAD, cpe, &manifest_size); + Array* buf = MetadataFactory::new_array(loader_data, + manifest_size, + CHECK); + char* p = (char*)(buf->data()); + memcpy(p, manifest, manifest_size); + ent->set_manifest(buf); } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/cds/filemap.hpp openjdk-21-21.0.2+13/src/hotspot/share/cds/filemap.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/cds/filemap.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/cds/filemap.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -53,7 +53,6 @@ enum { modules_image_entry, jar_entry, - signed_jar_entry, dir_entry, non_existent_entry, unknown_entry @@ -90,10 +89,6 @@ bool is_dir() const { return _type == dir_entry; } bool is_modules_image() const { return _type == modules_image_entry; } bool is_jar() const { return _type == jar_entry; } - bool is_signed() const { return _type == signed_jar_entry; } - void set_is_signed() { - _type = signed_jar_entry; - } bool from_class_path_attr() { return _from_class_path_attr; } time_t timestamp() const { return _timestamp; } const char* name() const; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/cds/unregisteredClasses.cpp openjdk-21-21.0.2+13/src/hotspot/share/cds/unregisteredClasses.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/cds/unregisteredClasses.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/cds/unregisteredClasses.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -46,11 +46,9 @@ assert(name != nullptr, "invariant"); assert(DumpSharedSpaces, "this function is only used with -Xshare:dump"); - { - PerfClassTraceTime vmtimer(ClassLoader::perf_sys_class_lookup_time(), - THREAD->get_thread_stat()->perf_timers_addr(), - PerfClassTraceTime::CLASS_LOAD); - } + PerfClassTraceTime vmtimer(ClassLoader::perf_app_classload_time(), + THREAD->get_thread_stat()->perf_timers_addr(), + PerfClassTraceTime::CLASS_LOAD); Symbol* path_symbol = SymbolTable::new_symbol(path); Handle url_classloader = get_url_classloader(path_symbol, CHECK_NULL); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/classfile/classFileParser.cpp openjdk-21-21.0.2+13/src/hotspot/share/classfile/classFileParser.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/classfile/classFileParser.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/classfile/classFileParser.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -4321,6 +4321,7 @@ (same_module) ? this_klass->joint_in_module_of_loader(k) : this_klass->class_in_module_of_loader(), (same_module) ? "" : "; ", (same_module) ? "" : k->class_in_module_of_loader()); + return; } else { // Add additional message content. Exceptions::fthrow( @@ -4328,6 +4329,7 @@ vmSymbols::java_lang_IllegalAccessError(), "superinterface check failed: %s", msg); + return; } } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/classfile/classLoader.cpp openjdk-21-21.0.2+13/src/hotspot/share/classfile/classLoader.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/classfile/classLoader.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/classfile/classLoader.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -122,7 +122,6 @@ PerfCounter* ClassLoader::_perf_classes_linked = nullptr; PerfCounter* ClassLoader::_perf_class_link_time = nullptr; PerfCounter* ClassLoader::_perf_class_link_selftime = nullptr; -PerfCounter* ClassLoader::_perf_sys_class_lookup_time = nullptr; PerfCounter* ClassLoader::_perf_shared_classload_time = nullptr; PerfCounter* ClassLoader::_perf_sys_classload_time = nullptr; PerfCounter* ClassLoader::_perf_app_classload_time = nullptr; @@ -1368,7 +1367,6 @@ NEWPERFEVENTCOUNTER(_perf_classes_linked, SUN_CLS, "linkedClasses"); NEWPERFEVENTCOUNTER(_perf_classes_verified, SUN_CLS, "verifiedClasses"); - NEWPERFTICKCOUNTER(_perf_sys_class_lookup_time, SUN_CLS, "lookupSysClassTime"); NEWPERFTICKCOUNTER(_perf_shared_classload_time, SUN_CLS, "sharedClassLoadTime"); NEWPERFTICKCOUNTER(_perf_sys_classload_time, SUN_CLS, "sysClassLoadTime"); NEWPERFTICKCOUNTER(_perf_app_classload_time, SUN_CLS, "appClassLoadTime"); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/classfile/classLoader.hpp openjdk-21-21.0.2+13/src/hotspot/share/classfile/classLoader.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/classfile/classLoader.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/classfile/classLoader.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -168,7 +168,6 @@ static PerfCounter* _perf_classes_linked; static PerfCounter* _perf_class_link_time; static PerfCounter* _perf_class_link_selftime; - static PerfCounter* _perf_sys_class_lookup_time; static PerfCounter* _perf_shared_classload_time; static PerfCounter* _perf_sys_classload_time; static PerfCounter* _perf_app_classload_time; @@ -289,7 +288,6 @@ static PerfCounter* perf_classes_linked() { return _perf_classes_linked; } static PerfCounter* perf_class_link_time() { return _perf_class_link_time; } static PerfCounter* perf_class_link_selftime() { return _perf_class_link_selftime; } - static PerfCounter* perf_sys_class_lookup_time() { return _perf_sys_class_lookup_time; } static PerfCounter* perf_shared_classload_time() { return _perf_shared_classload_time; } static PerfCounter* perf_sys_classload_time() { return _perf_sys_classload_time; } static PerfCounter* perf_app_classload_time() { return _perf_app_classload_time; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/classfile/verifier.cpp openjdk-21-21.0.2+13/src/hotspot/share/classfile/verifier.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/classfile/verifier.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/classfile/verifier.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2250,11 +2250,12 @@ "low must be less than or equal to high in tableswitch"); return; } - keys = high - low + 1; - if (keys < 0) { + int64_t keys64 = ((int64_t)high - low) + 1; + if (keys64 > 65535) { // Max code length verify_error(ErrorContext::bad_code(bci), "too many keys in tableswitch"); return; } + keys = (int)keys64; delta = 1; } else { keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/code/codeBlob.cpp openjdk-21-21.0.2+13/src/hotspot/share/code/codeBlob.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/code/codeBlob.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/code/codeBlob.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -204,7 +204,8 @@ if (PrintStubCode) { ttyLocker ttyl; tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); - tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub); + tty->print_cr("Decoding %s " PTR_FORMAT " [" PTR_FORMAT ", " PTR_FORMAT "] (%d bytes)", + stub_id, p2i(stub), p2i(stub->code_begin()), p2i(stub->code_end()), stub->code_size()); Disassembler::decode(stub->code_begin(), stub->code_end(), tty NOT_PRODUCT(COMMA &stub->asm_remarks())); if ((stub->oop_maps() != nullptr) && AbstractDisassembler::show_structs()) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/code/vtableStubs.cpp openjdk-21-21.0.2+13/src/hotspot/share/code/vtableStubs.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/code/vtableStubs.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/code/vtableStubs.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -230,8 +230,9 @@ enter(is_vtable_stub, vtable_index, s); if (PrintAdapterHandlers) { - tty->print_cr("Decoding VtableStub %s[%d]@" INTX_FORMAT, - is_vtable_stub? "vtbl": "itbl", vtable_index, p2i(VtableStub::receiver_location())); + tty->print_cr("Decoding VtableStub %s[%d]@" PTR_FORMAT " [" PTR_FORMAT ", " PTR_FORMAT "] (" SIZE_FORMAT " bytes)", + is_vtable_stub? "vtbl": "itbl", vtable_index, p2i(VtableStub::receiver_location()), + p2i(s->code_begin()), p2i(s->code_end()), pointer_delta(s->code_end(), s->code_begin(), 1)); Disassembler::decode(s->code_begin(), s->code_end()); } // Notify JVMTI about this stub. The event will be recorded by the enclosing diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/compiler/compileBroker.cpp openjdk-21-21.0.2+13/src/hotspot/share/compiler/compileBroker.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/compiler/compileBroker.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/compiler/compileBroker.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2651,8 +2651,8 @@ int total_bailout_count = CompileBroker::_total_bailout_count; int total_invalidated_count = CompileBroker::_total_invalidated_count; - int nmethods_size = CompileBroker::_sum_nmethod_code_size; - int nmethods_code_size = CompileBroker::_sum_nmethod_size; + int nmethods_code_size = CompileBroker::_sum_nmethod_code_size; + int nmethods_size = CompileBroker::_sum_nmethod_size; tty->cr(); tty->print_cr("Accumulated compiler times"); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shared/barrierSetNMethod.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shared/barrierSetNMethod.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shared/barrierSetNMethod.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shared/barrierSetNMethod.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -186,6 +186,14 @@ // Called upon first entry after being armed bool may_enter = bs_nm->nmethod_entry_barrier(nm); + // In case a concurrent thread disarmed the nmethod, we need to ensure the new instructions + // are made visible, by using a cross modify fence. Note that this is synchronous cross modifying + // code, where the existence of new instructions is communicated via data (the guard value). + // This cross modify fence is only needed when the nmethod entry barrier modifies the + // instructions. Not all platforms currently do that, so if this check becomes expensive, + // it can be made conditional on the nmethod_patching_type. + OrderAccess::cross_modify_fence(); + // Diagnostic option to force deoptimization 1 in 3 times. It is otherwise // a very rare event. if (DeoptimizeNMethodBarriersALot) { @@ -214,6 +222,7 @@ assert(nm->is_osr_method(), "Should not reach here"); log_trace(nmethod, barrier)("Running osr nmethod entry barrier: " PTR_FORMAT, p2i(nm)); + bool result = nmethod_entry_barrier(nm); OrderAccess::cross_modify_fence(); - return nmethod_entry_barrier(nm); + return result; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -675,8 +675,15 @@ Node* payload_size = size; Node* offset = kit->MakeConX(base_off); payload_size = kit->gvn().transform(new SubXNode(payload_size, offset)); + if (is_array) { + // Ensure the array payload size is rounded up to the next BytesPerLong + // multiple when converting to double-words. This is necessary because array + // size does not include object alignment padding, so it might not be a + // multiple of BytesPerLong for sub-long element types. + payload_size = kit->gvn().transform(new AddXNode(payload_size, kit->MakeConX(BytesPerLong - 1))); + } payload_size = kit->gvn().transform(new URShiftXNode(payload_size, kit->intcon(LogBytesPerLong))); - ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, src_base, offset, dst_base, offset, payload_size, true, false); + ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, src_base, offset, dst_base, offset, payload_size, true, false); if (is_array) { ac->set_clone_array(); } else { diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shared/tlab_globals.hpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shared/tlab_globals.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shared/tlab_globals.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shared/tlab_globals.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -70,10 +70,13 @@ "Allocation averaging weight") \ range(0, 100) \ \ + /* At GC all TLABs are retired, and each thread's active */ \ + /* TLAB is assumed to be half full on average. The */ \ + /* remaining space is waste, proportional to TLAB size. */ \ + product(uintx, TLABWasteTargetPercent, 1, \ + "Percentage of Eden that can be wasted (half-full TLABs at GC)") \ /* Limit the lower bound of this flag to 1 as it is used */ \ /* in a division expression. */ \ - product(uintx, TLABWasteTargetPercent, 1, \ - "Percentage of Eden that can be wasted") \ range(1, 100) \ \ product(uintx, TLABRefillWasteFraction, 64, \ diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -63,6 +63,7 @@ C->clear_major_progress(); C->process_for_post_loop_opts_igvn(igvn); + if (C->failing()) return false; } C->set_post_loop_opts_phase(); // now for real! } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -59,7 +59,6 @@ SHENANDOAH_CHECK_FLAG_SET(ShenandoahIUBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahNMethodBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahStackWatermarkBarrier); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -49,7 +49,6 @@ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahIUBarrier); SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCASBarrier); SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier); - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahNMethodBarrier); SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStackWatermarkBarrier); // Final configuration checks diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -47,7 +47,6 @@ SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahNMethodBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahStackWatermarkBarrier); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -45,7 +45,7 @@ BarrierSet(make_barrier_set_assembler(), make_barrier_set_c1(), make_barrier_set_c2(), - ShenandoahNMethodBarrier ? new ShenandoahBarrierSetNMethod(heap) : nullptr, + new ShenandoahBarrierSetNMethod(heap), new ShenandoahBarrierSetStackChunk(), BarrierSet::FakeRtti(BarrierSet::ShenandoahBarrierSet)), _heap(heap), diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -104,6 +104,20 @@ ShenandoahNMethodTable* ShenandoahCodeRoots::_nmethod_table; int ShenandoahCodeRoots::_disarmed_value = 1; +bool ShenandoahCodeRoots::use_nmethod_barriers_for_mark() { + // Continuations need nmethod barriers for scanning stack chunk nmethods. + if (Continuations::enabled()) return true; + + // Concurrent class unloading needs nmethod barriers. + // When a nmethod is about to be executed, we need to make sure that all its + // metadata are marked. The alternative is to remark thread roots at final mark + // pause, which would cause latency issues. + if (ShenandoahHeap::heap()->unload_classes()) return true; + + // Otherwise, we can go without nmethod barriers. + return false; +} + void ShenandoahCodeRoots::initialize() { _nmethod_table = new ShenandoahNMethodTable(); } @@ -118,8 +132,13 @@ _nmethod_table->unregister_nmethod(nm); } -void ShenandoahCodeRoots::arm_nmethods() { - assert(BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr, "Sanity"); +void ShenandoahCodeRoots::arm_nmethods_for_mark() { + if (use_nmethod_barriers_for_mark()) { + BarrierSet::barrier_set()->barrier_set_nmethod()->arm_all_nmethods(); + } +} + +void ShenandoahCodeRoots::arm_nmethods_for_evac() { BarrierSet::barrier_set()->barrier_set_nmethod()->arm_all_nmethods(); } @@ -163,7 +182,7 @@ }; void ShenandoahCodeRoots::disarm_nmethods() { - if (ShenandoahNMethodBarrier) { + if (use_nmethod_barriers_for_mark()) { ShenandoahDisarmNMethodsTask task; ShenandoahHeap::heap()->workers()->run_task(&task); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -97,11 +97,14 @@ // Concurrent nmethod unloading support static void unlink(WorkerThreads* workers, bool unloading_occurred); static void purge(); - static void arm_nmethods(); + static void arm_nmethods_for_mark(); + static void arm_nmethods_for_evac(); static void disarm_nmethods(); static int disarmed_value() { return _disarmed_value; } static int* disarmed_value_address() { return &_disarmed_value; } + static bool use_nmethod_barriers_for_mark(); + private: static ShenandoahNMethodTable* _nmethod_table; static int _disarmed_value; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.hpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -40,7 +40,8 @@ private: size_t _success_concurrent_gcs; size_t _success_degenerated_gcs; - size_t _success_full_gcs; + // Written by control thread, read by mutators + volatile size_t _success_full_gcs; size_t _alloc_failure_degenerated; size_t _alloc_failure_degenerated_upgrade_to_full; size_t _alloc_failure_full; @@ -82,6 +83,10 @@ size_t cycle_counter() const; void print_gc_stats(outputStream* out) const; + + size_t full_gc_count() const { + return _success_full_gcs + _alloc_failure_degenerated_upgrade_to_full; + } }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCOLLECTORPOLICY_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -545,12 +545,9 @@ // Make above changes visible to worker threads OrderAccess::fence(); - // Arm nmethods for concurrent marking. When a nmethod is about to be executed, - // we need to make sure that all its metadata are marked. alternative is to remark - // thread roots at final mark pause, but it can be potential latency killer. - if (heap->unload_classes()) { - ShenandoahCodeRoots::arm_nmethods(); - } + + // Arm nmethods for concurrent mark + ShenandoahCodeRoots::arm_nmethods_for_mark(); ShenandoahStackWatermark::change_epoch_id(); if (ShenandoahPacing) { @@ -603,7 +600,7 @@ } // Arm nmethods/stack for concurrent processing - ShenandoahCodeRoots::arm_nmethods(); + ShenandoahCodeRoots::arm_nmethods_for_evac(); ShenandoahStackWatermark::change_epoch_id(); if (ShenandoahPacing) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -181,11 +181,9 @@ assert(!heap->cancelled_gc(), "STW reference update can not OOM"); } - if (ClassUnloading) { - // Disarm nmethods that armed in concurrent cycle. - // In above case, update roots should disarm them - ShenandoahCodeRoots::disarm_nmethods(); - } + // Disarm nmethods that armed in concurrent cycle. + // In above case, update roots should disarm them + ShenandoahCodeRoots::disarm_nmethods(); op_cleanup_complete(); break; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -838,25 +838,14 @@ // It might happen that one of the threads requesting allocation would unblock // way later after GC happened, only to fail the second allocation, because // other threads have already depleted the free storage. In this case, a better - // strategy is to try again, as long as GC makes progress. - // - // Then, we need to make sure the allocation was retried after at least one - // Full GC, which means we want to try more than ShenandoahFullGCThreshold times. - - size_t tries = 0; - - while (result == nullptr && _progress_last_gc.is_set()) { - tries++; + // strategy is to try again, as long as GC makes progress (or until at least + // one full GC has completed). + size_t original_count = shenandoah_policy()->full_gc_count(); + while (result == nullptr + && (_progress_last_gc.is_set() || original_count == shenandoah_policy()->full_gc_count())) { control_thread()->handle_alloc_failure(req); result = allocate_memory_under_lock(req, in_new_region); } - - while (result == nullptr && tries <= ShenandoahFullGCThreshold) { - tries++; - control_thread()->handle_alloc_failure(req); - result = allocate_memory_under_lock(req, in_new_region); - } - } else { assert(req.is_gc_alloc(), "Can only accept GC allocs here"); result = allocate_memory_under_lock(req, in_new_region); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -80,9 +80,7 @@ void ShenandoahNMethod::disarm_nmethod(nmethod* nm) { BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod(); - assert(bs != nullptr || !ShenandoahNMethodBarrier, - "Must have nmethod barrier for concurrent GC"); - if (bs != nullptr && bs->is_armed(nm)) { + if (bs->is_armed(nm)) { bs->disarm(nm); } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -206,7 +206,7 @@ void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations); ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops); - CodeBlobToOopClosure* adjust_code_closure = (ClassUnloading && ShenandoahNMethodBarrier) ? + CodeBlobToOopClosure* adjust_code_closure = ShenandoahCodeRoots::use_nmethod_barriers_for_mark() ? static_cast(&blobs_and_disarm_Cl) : static_cast(&code_blob_cl); CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -172,7 +172,7 @@ void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) { CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations); ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(keep_alive); - CodeBlobToOopClosure* codes_cl = (ClassUnloading && ShenandoahNMethodBarrier) ? + CodeBlobToOopClosure* codes_cl = ShenandoahCodeRoots::use_nmethod_barriers_for_mark() ? static_cast(&blobs_and_disarm_Cl) : static_cast(&update_blobs); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -89,8 +89,13 @@ } void ShenandoahSTWMark::mark() { - // Weak reference processing ShenandoahHeap* const heap = ShenandoahHeap::heap(); + + // Arm all nmethods. Even though this is STW mark, some marking code + // piggybacks on nmethod barriers for special instances. + ShenandoahCodeRoots::arm_nmethods_for_mark(); + + // Weak reference processing ShenandoahReferenceProcessor* rp = heap->ref_processor(); rp->reset_thread_locals(); rp->set_soft_reference_policy(heap->soft_ref_policy()->should_clear_all_soft_refs()); @@ -120,6 +125,9 @@ heap->mark_complete_marking_context(); end_mark(); + // Mark is finished, can disarm the nmethods now. + ShenandoahCodeRoots::disarm_nmethods(); + assert(task_queues()->is_empty(), "Should be empty"); TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats()); TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats()); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -32,6 +32,7 @@ #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "gc/shenandoah/shenandoahVMOperations.hpp" +#include "interpreter/oopMapCache.hpp" #include "memory/universe.hpp" bool VM_ShenandoahReferenceOperation::doit_prologue() { @@ -40,6 +41,7 @@ } void VM_ShenandoahReferenceOperation::doit_epilogue() { + OopMapCache::cleanup_old_entries(); if (Universe::has_reference_pending_list()) { Heap_lock->notify_all(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -352,9 +352,6 @@ product(bool, ShenandoahLoadRefBarrier, true, DIAGNOSTIC, \ "Turn on/off load-reference barriers in Shenandoah") \ \ - product(bool, ShenandoahNMethodBarrier, true, DIAGNOSTIC, \ - "Turn on/off NMethod entry barriers in Shenandoah") \ - \ product(bool, ShenandoahStackWatermarkBarrier, true, DIAGNOSTIC, \ "Turn on/off stack watermark barriers in Shenandoah") \ \ diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp openjdk-21-21.0.2+13/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -42,6 +42,7 @@ #include "opto/rootnode.hpp" #include "opto/runtime.hpp" #include "opto/type.hpp" +#include "utilities/debug.hpp" #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" @@ -226,6 +227,7 @@ } ZLoadBarrierStubC2* ZLoadBarrierStubC2::create(const MachNode* node, Address ref_addr, Register ref) { + AARCH64_ONLY(fatal("Should use ZLoadBarrierStubC2Aarch64::create")); ZLoadBarrierStubC2* const stub = new (Compile::current()->comp_arena()) ZLoadBarrierStubC2(node, ref_addr, ref); register_stub(stub); @@ -275,6 +277,7 @@ } ZStoreBarrierStubC2* ZStoreBarrierStubC2::create(const MachNode* node, Address ref_addr, Register new_zaddress, Register new_zpointer, bool is_native, bool is_atomic) { + AARCH64_ONLY(fatal("Should use ZStoreBarrierStubC2Aarch64::create")); ZStoreBarrierStubC2* const stub = new (Compile::current()->comp_arena()) ZStoreBarrierStubC2(node, ref_addr, new_zaddress, new_zpointer, is_native, is_atomic); register_stub(stub); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp openjdk-21-21.0.2+13/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -52,9 +52,9 @@ static int trampoline_stubs_count(); static int stubs_start_offset(); -public: ZBarrierStubC2(const MachNode* node); +public: RegMask& live() const; Label* entry(); Label* continuation(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/interpreter/bytecodes.cpp openjdk-21-21.0.2+13/src/hotspot/share/interpreter/bytecodes.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/interpreter/bytecodes.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/interpreter/bytecodes.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -385,12 +385,18 @@ if (end != nullptr && aligned_bcp + 3*jintSize >= end) { return -1; // don't read past end of code buffer } + // Promote calculation to signed 64 bits to do range checks, used by the verifier. jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize); jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize); jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize; - // only return len if it can be represented as a positive int; - // return -1 otherwise - return (len > 0 && len == (int)len) ? len : -1; + // Only return len if it can be represented as a positive int and lo <= hi. + // The caller checks for bytecode stream overflow. + if (lo <= hi && len == (int)len) { + assert(len > 0, "must be"); + return (int)len; + } else { + return -1; + } } case _lookupswitch: // fall through @@ -402,9 +408,13 @@ } jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize); jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize; - // only return len if it can be represented as a positive int; - // return -1 otherwise - return (len > 0 && len == (int)len) ? len : -1; + // Only return len if it can be represented as a positive int and npairs >= 0. + if (npairs >= 0 && len == (int)len) { + assert(len > 0, "must be"); + return (int)len; + } else { + return -1; + } } default: // Note: Length functions must return <=0 for invalid bytecodes. diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/memory/metaspace.cpp openjdk-21-21.0.2+13/src/hotspot/share/memory/metaspace.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/memory/metaspace.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/memory/metaspace.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -567,12 +567,6 @@ "wrong alignment"); MetaspaceContext::initialize_class_space_context(rs); - - // This does currently not work because rs may be the result of a split - // operation and NMT seems not to be able to handle splits. - // Will be fixed with JDK-8243535. - // MemTracker::record_virtual_memory_type((address)rs.base(), mtClass); - } // Returns true if class space has been setup (initialize_class_space). @@ -837,6 +831,9 @@ CompressedClassSpaceSize)); } + // Mark class space as such + MemTracker::record_virtual_memory_type((address)rs.base(), mtClass); + // Initialize space Metaspace::initialize_class_space(rs); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/oops/fieldStreams.hpp openjdk-21-21.0.2+13/src/hotspot/share/oops/fieldStreams.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/oops/fieldStreams.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/oops/fieldStreams.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -37,6 +37,7 @@ // iterates over fields that have been injected by the JVM. // AllFieldStream exposes all fields and should only be used in rare // cases. +// HierarchicalFieldStream allows to also iterate over fields of supertypes. class FieldStreamBase : public StackObj { protected: const Array* _fieldinfo_stream; @@ -135,7 +136,7 @@ } }; -// Iterate over only the internal fields +// Iterate over only the Java fields class JavaFieldStream : public FieldStreamBase { public: JavaFieldStream(const InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants(), 0, k->java_fields_count()) {} @@ -179,4 +180,104 @@ AllFieldStream(const InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants()) {} }; +// Iterate over fields including the ones declared in supertypes +template +class HierarchicalFieldStream : public StackObj { + private: + const Array* _interfaces; + InstanceKlass* _next_klass; // null indicates no more type to visit + FieldStreamType _current_stream; + int _interface_index; + + void prepare() { + _next_klass = next_klass_with_fields(); + // special case: the initial klass has no fields. If any supertype has any fields, use that directly. + // if no such supertype exists, done() will return false already. + next_stream_if_done(); + } + + InstanceKlass* next_klass_with_fields() { + assert(_next_klass != nullptr, "reached end of types already"); + InstanceKlass* result = _next_klass; + do { + if (!result->is_interface() && result->super() != nullptr) { + result = result->java_super(); + } else if (_interface_index > 0) { + result = _interfaces->at(--_interface_index); + } else { + return nullptr; // we did not find any more supertypes with fields + } + } while (FieldStreamType(result).done()); + return result; + } + + // sets _current_stream to the next if the current is done and any more is available + void next_stream_if_done() { + if (_next_klass != nullptr && _current_stream.done()) { + _current_stream = FieldStreamType(_next_klass); + assert(!_current_stream.done(), "created empty stream"); + _next_klass = next_klass_with_fields(); + } + } + + public: + HierarchicalFieldStream(InstanceKlass* klass) : + _interfaces(klass->transitive_interfaces()), + _next_klass(klass), + _current_stream(FieldStreamType(klass)), + _interface_index(_interfaces->length()) { + prepare(); + } + + void next() { + _current_stream.next(); + next_stream_if_done(); + } + + bool done() const { return _next_klass == nullptr && _current_stream.done(); } + + // bridge functions from FieldStreamBase + + AccessFlags access_flags() const { + return _current_stream.access_flags(); + } + + FieldInfo::FieldFlags field_flags() const { + return _current_stream.field_flags(); + } + + Symbol* name() const { + return _current_stream.name(); + } + + Symbol* signature() const { + return _current_stream.signature(); + } + + Symbol* generic_signature() const { + return _current_stream.generic_signature(); + } + + int offset() const { + return _current_stream.offset(); + } + + bool is_contended() const { + return _current_stream.is_contended(); + } + + int contended_group() const { + return _current_stream.contended_group(); + } + + FieldInfo to_FieldInfo() { + return _current_stream.to_FieldInfo(); + } + + fieldDescriptor& field_descriptor() const { + return _current_stream.field_descriptor(); + } + +}; + #endif // SHARE_OOPS_FIELDSTREAMS_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/oops/symbol.cpp openjdk-21-21.0.2+13/src/hotspot/share/oops/symbol.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/oops/symbol.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/oops/symbol.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -22,7 +22,6 @@ * */ - #include "precompiled.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/altHashing.hpp" @@ -390,11 +389,9 @@ // The print_value functions are present in all builds, to support the // disassembler and error reporting. void Symbol::print_value_on(outputStream* st) const { - st->print("'"); - for (int i = 0; i < utf8_length(); i++) { - st->print("%c", char_at(i)); - } - st->print("'"); + st->print_raw("'", 1); + st->print_raw((const char*)base(), utf8_length()); + st->print_raw("'", 1); } void Symbol::print_value() const { print_value_on(tty); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/addnode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/addnode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/addnode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/addnode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -283,8 +283,26 @@ assert( in1->in(2) != this && in2->in(2) != this, "dead loop in AddINode::Ideal" ); Node* sub = SubNode::make(nullptr, nullptr, bt); - sub->init_req(1, phase->transform(AddNode::make(in1->in(1), in2->in(1), bt))); - sub->init_req(2, phase->transform(AddNode::make(in1->in(2), in2->in(2), bt))); + Node* sub_in1; + PhaseIterGVN* igvn = phase->is_IterGVN(); + // During IGVN, if both inputs of the new AddNode are a tree of SubNodes, this same transformation will be applied + // to every node of the tree. Calling transform() causes the transformation to be applied recursively, once per + // tree node whether some subtrees are identical or not. Pushing to the IGVN worklist instead, causes the transform + // to be applied once per unique subtrees (because all uses of a subtree are updated with the result of the + // transformation). In case of a large tree, this can make a difference in compilation time. + if (igvn != nullptr) { + sub_in1 = igvn->register_new_node_with_optimizer(AddNode::make(in1->in(1), in2->in(1), bt)); + } else { + sub_in1 = phase->transform(AddNode::make(in1->in(1), in2->in(1), bt)); + } + Node* sub_in2; + if (igvn != nullptr) { + sub_in2 = igvn->register_new_node_with_optimizer(AddNode::make(in1->in(2), in2->in(2), bt)); + } else { + sub_in2 = phase->transform(AddNode::make(in1->in(2), in2->in(2), bt)); + } + sub->init_req(1, sub_in1); + sub->init_req(2, sub_in2); return sub; } // Convert "(a-b)+(b+c)" into "(a+c)" diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/arraycopynode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/arraycopynode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/arraycopynode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/arraycopynode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -134,12 +134,13 @@ assert (ary_src != nullptr, "not an array or instance?"); // clone passes a length as a rounded number of longs. If we're // cloning an array we'll do it element by element. If the - // length input to ArrayCopyNode is constant, length of input - // array must be too. - - assert((get_length_if_constant(phase) == -1) != ary_src->size()->is_con() || + // length of the input array is constant, ArrayCopyNode::Length + // must be too. Note that the opposite does not need to hold, + // because different input array lengths (e.g. int arrays with + // 3 or 4 elements) might lead to the same length input + // (e.g. 2 double-words). + assert(!ary_src->size()->is_con() || (get_length_if_constant(phase) >= 0) || phase->is_IterGVN() || phase->C->inlining_incrementally() || StressReflectiveCode, "inconsistent"); - if (ary_src->size()->is_con()) { return ary_src->size()->get_con(); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/c2compiler.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/c2compiler.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/c2compiler.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/c2compiler.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -113,6 +113,7 @@ bool do_locks_coarsening = EliminateLocks; while (!env->failing()) { + ResourceMark rm; // Attempt to compile while subsuming loads into machine instructions. Options options(subsume_loads, do_escape_analysis, do_iterative_escape_analysis, eliminate_boxing, do_locks_coarsening, install_code); Compile C(env, target, entry_bci, options, directive); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/callGenerator.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/callGenerator.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/callGenerator.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/callGenerator.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -97,6 +97,8 @@ } Parse parser(jvms, method(), _expected_uses); + if (C->failing()) return nullptr; + // Grab signature for matching/allocation GraphKit& exits = parser.exits(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/castnode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/castnode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/castnode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/castnode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -36,14 +36,14 @@ //============================================================================= // If input is already higher or equal to cast type, then this is an identity. Node* ConstraintCastNode::Identity(PhaseGVN* phase) { + if (_dependency == UnconditionalDependency) { + return this; + } Node* dom = dominating_cast(phase, phase); if (dom != nullptr) { return dom; } - if (_dependency != RegularDependency) { - return this; - } - return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this; + return higher_equal_types(phase, in(1)) ? in(1) : this; } //------------------------------Value------------------------------------------ @@ -100,47 +100,62 @@ return (in(0) && remove_dead_region(phase, can_reshape)) ? this : nullptr; } +uint ConstraintCastNode::hash() const { + return TypeNode::hash() + (int)_dependency + (_extra_types != nullptr ? _extra_types->hash() : 0); +} + bool ConstraintCastNode::cmp(const Node &n) const { - return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._dependency == _dependency; + if (!TypeNode::cmp(n)) { + return false; + } + ConstraintCastNode& cast = (ConstraintCastNode&) n; + if (cast._dependency != _dependency) { + return false; + } + if (_extra_types == nullptr || cast._extra_types == nullptr) { + return _extra_types == cast._extra_types; + } + return _extra_types->eq(cast._extra_types); } uint ConstraintCastNode::size_of() const { return sizeof(*this); } -Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency) { +Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency, + const TypeTuple* extra_types) { switch(opcode) { case Op_CastII: { - Node* cast = new CastIINode(n, t, dependency); + Node* cast = new CastIINode(n, t, dependency, false, extra_types); cast->set_req(0, c); return cast; } case Op_CastLL: { - Node* cast = new CastLLNode(n, t, dependency); + Node* cast = new CastLLNode(n, t, dependency, extra_types); cast->set_req(0, c); return cast; } case Op_CastPP: { - Node* cast = new CastPPNode(n, t, dependency); + Node* cast = new CastPPNode(n, t, dependency, extra_types); cast->set_req(0, c); return cast; } case Op_CastFF: { - Node* cast = new CastFFNode(n, t, dependency); + Node* cast = new CastFFNode(n, t, dependency, extra_types); cast->set_req(0, c); return cast; } case Op_CastDD: { - Node* cast = new CastDDNode(n, t, dependency); + Node* cast = new CastDDNode(n, t, dependency, extra_types); cast->set_req(0, c); return cast; } case Op_CastVV: { - Node* cast = new CastVVNode(n, t, dependency); + Node* cast = new CastVVNode(n, t, dependency, extra_types); cast->set_req(0, c); return cast; } - case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency); + case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency, extra_types); default: fatal("Bad opcode %d", opcode); } @@ -150,10 +165,10 @@ Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt) { switch(bt) { case T_INT: { - return make_cast(Op_CastII, c, n, t, dependency); + return make_cast(Op_CastII, c, n, t, dependency, nullptr); } case T_LONG: { - return make_cast(Op_CastLL, c, n, t, dependency); + return make_cast(Op_CastLL, c, n, t, dependency, nullptr); } default: fatal("Bad basic type %s", type2name(bt)); @@ -186,7 +201,7 @@ u->outcnt() > 0 && u->Opcode() == opc && u->in(0) != nullptr && - u->bottom_type()->higher_equal(type())) { + higher_equal_types(gvn, u)) { if (pt->is_dominator(u->in(0), ctl)) { return u->as_Type(); } @@ -202,9 +217,28 @@ return nullptr; } +bool ConstraintCastNode::higher_equal_types(PhaseGVN* phase, const Node* other) const { + const Type* t = phase->type(other); + if (!t->higher_equal_speculative(type())) { + return false; + } + if (_extra_types != nullptr) { + for (uint i = 0; i < _extra_types->cnt(); ++i) { + if (!t->higher_equal_speculative(_extra_types->field_at(i))) { + return false; + } + } + } + return true; +} + #ifndef PRODUCT void ConstraintCastNode::dump_spec(outputStream *st) const { TypeNode::dump_spec(st); + if (_extra_types != nullptr) { + st->print(" extra types: "); + _extra_types->dump_on(st); + } if (_dependency != RegularDependency) { st->print(" %s dependency", _dependency == StrongDependency ? "strong" : "unconditional"); } @@ -523,20 +557,21 @@ return this; } -Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency) { +Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency, + const TypeTuple* types) { Node* cast= nullptr; if (type->isa_int()) { - cast = make_cast(Op_CastII, c, in, type, dependency); + cast = make_cast(Op_CastII, c, in, type, dependency, types); } else if (type->isa_long()) { - cast = make_cast(Op_CastLL, c, in, type, dependency); + cast = make_cast(Op_CastLL, c, in, type, dependency, types); } else if (type->isa_float()) { - cast = make_cast(Op_CastFF, c, in, type, dependency); + cast = make_cast(Op_CastFF, c, in, type, dependency, types); } else if (type->isa_double()) { - cast = make_cast(Op_CastDD, c, in, type, dependency); + cast = make_cast(Op_CastDD, c, in, type, dependency, types); } else if (type->isa_vect()) { - cast = make_cast(Op_CastVV, c, in, type, dependency); + cast = make_cast(Op_CastVV, c, in, type, dependency, types); } else if (type->isa_ptr()) { - cast = make_cast(Op_CastPP, c, in, type, dependency); + cast = make_cast(Op_CastPP, c, in, type, dependency, types); } return cast; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/castnode.hpp openjdk-21-21.0.2+13/src/hotspot/share/opto/castnode.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/castnode.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/castnode.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -43,11 +43,20 @@ const DependencyType _dependency; virtual bool cmp( const Node &n ) const; virtual uint size_of() const; + virtual uint hash() const; // Check the type const Type* widen_type(const PhaseGVN* phase, const Type* res, BasicType bt) const; + private: + // PhiNode::Ideal() transforms a Phi that merges a single uncasted value into a single cast pinned at the region. + // The types of cast nodes eliminated as a consequence of this transformation are collected and stored here so the + // type dependencies carried by the cast are known. The cast can then be eliminated if the type of its input is + // narrower (or equal) than all the types it carries. + const TypeTuple* _extra_types; + public: - ConstraintCastNode(Node *n, const Type *t, DependencyType dependency) - : TypeNode(t,2), _dependency(dependency) { + ConstraintCastNode(Node* n, const Type* t, ConstraintCastNode::DependencyType dependency, + const TypeTuple* extra_types) + : TypeNode(t,2), _dependency(dependency), _extra_types(extra_types) { init_class_id(Class_ConstraintCast); init_req(1, n); } @@ -59,14 +68,15 @@ virtual bool depends_only_on_test() const { return _dependency == RegularDependency; } bool carry_dependency() const { return _dependency != RegularDependency; } TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const; - static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency); + static Node* make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency, const TypeTuple* extra_types); static Node* make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt); #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif - static Node* make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency); + static Node* make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency, + const TypeTuple* types); Node* optimize_integer_cast(PhaseGVN* phase, BasicType bt); @@ -91,6 +101,16 @@ } } } + + bool higher_equal_types(PhaseGVN* phase, const Node* other) const; + + int extra_types_count() const { + return _extra_types == nullptr ? 0 : _extra_types->cnt(); + } + + const Type* extra_type_at(int i) const { + return _extra_types->field_at(i); + } }; //------------------------------CastIINode------------------------------------- @@ -103,12 +123,12 @@ virtual uint size_of() const; public: - CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false) - : ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) { + CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr) + : ConstraintCastNode(n, t, dependency, types), _range_check_dependency(range_check_dependency) { init_class_id(Class_CastII); } CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false) - : ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) { + : ConstraintCastNode(n, t, dependency, nullptr), _range_check_dependency(range_check_dependency) { init_class_id(Class_CastII); init_req(0, ctrl); } @@ -134,12 +154,12 @@ class CastLLNode: public ConstraintCastNode { public: CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency) - : ConstraintCastNode(n, t, dependency) { + : ConstraintCastNode(n, t, dependency, nullptr) { init_class_id(Class_CastLL); init_req(0, ctrl); } - CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency) - : ConstraintCastNode(n, t, dependency){ + CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) + : ConstraintCastNode(n, t, dependency, types) { init_class_id(Class_CastLL); } @@ -151,8 +171,8 @@ class CastFFNode: public ConstraintCastNode { public: - CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency) - : ConstraintCastNode(n, t, dependency){ + CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) + : ConstraintCastNode(n, t, dependency, types) { init_class_id(Class_CastFF); } virtual int Opcode() const; @@ -161,8 +181,8 @@ class CastDDNode: public ConstraintCastNode { public: - CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency) - : ConstraintCastNode(n, t, dependency){ + CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) + : ConstraintCastNode(n, t, dependency, types) { init_class_id(Class_CastDD); } virtual int Opcode() const; @@ -171,8 +191,8 @@ class CastVVNode: public ConstraintCastNode { public: - CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency) - : ConstraintCastNode(n, t, dependency){ + CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) + : ConstraintCastNode(n, t, dependency, types) { init_class_id(Class_CastVV); } virtual int Opcode() const; @@ -184,8 +204,8 @@ // cast pointer to pointer (different type) class CastPPNode: public ConstraintCastNode { public: - CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency) - : ConstraintCastNode(n, t, dependency) { + CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) + : ConstraintCastNode(n, t, dependency, types) { } virtual int Opcode() const; virtual uint ideal_reg() const { return Op_RegP; } @@ -195,8 +215,8 @@ // for _checkcast, cast pointer to pointer (different type), without JOIN, class CheckCastPPNode: public ConstraintCastNode { public: - CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency) - : ConstraintCastNode(n, t, dependency) { + CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) + : ConstraintCastNode(n, t, dependency, types) { init_class_id(Class_CheckCastPP); init_req(0, c); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/cfgnode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/cfgnode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/cfgnode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/cfgnode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2085,10 +2085,12 @@ // Add casts to carry the control dependency of the Phi that is // going away Node* cast = nullptr; + const TypeTuple* extra_types = collect_types(phase); if (phi_type->isa_ptr()) { const Type* uin_type = phase->type(uin); if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) { - cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency); + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency, + extra_types); } else { // Use a CastPP for a cast to not null and a CheckCastPP for // a cast to a new klass (and both if both null-ness and @@ -2098,7 +2100,8 @@ // null, uin's type must be casted to not null if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() && uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) { - cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency); + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, + ConstraintCastNode::StrongDependency, extra_types); } // If the type of phi and uin, both casted to not null, @@ -2110,14 +2113,16 @@ cast = phase->transform(cast); n = cast; } - cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency); + cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency, + extra_types); } if (cast == nullptr) { - cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency); + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency, + extra_types); } } } else { - cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type, ConstraintCastNode::StrongDependency); + cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types); } assert(cast != nullptr, "cast should be set"); cast = phase->transform(cast); @@ -2512,6 +2517,52 @@ return progress; // Return any progress } +static int compare_types(const Type* const& e1, const Type* const& e2) { + return (intptr_t)e1 - (intptr_t)e2; +} + +// Collect types at casts that are going to be eliminated at that Phi and store them in a TypeTuple. +// Sort the types using an arbitrary order so a list of some types always hashes to the same TypeTuple (and TypeTuple +// pointer comparison is enough to tell if 2 list of types are the same or not) +const TypeTuple* PhiNode::collect_types(PhaseGVN* phase) const { + const Node* region = in(0); + const Type* phi_type = bottom_type(); + ResourceMark rm; + GrowableArray types; + for (uint i = 1; i < req(); i++) { + if (region->in(i) == nullptr || phase->type(region->in(i)) == Type::TOP) { + continue; + } + Node* in = Node::in(i); + const Type* t = phase->type(in); + if (in == nullptr || in == this || t == Type::TOP) { + continue; + } + if (t != phi_type && t->higher_equal_speculative(phi_type)) { + types.insert_sorted(t); + } + while (in != nullptr && in->is_ConstraintCast()) { + Node* next = in->in(1); + if (phase->type(next)->isa_rawptr() && phase->type(in)->isa_oopptr()) { + break; + } + ConstraintCastNode* cast = in->as_ConstraintCast(); + for (int j = 0; j < cast->extra_types_count(); ++j) { + const Type* extra_t = cast->extra_type_at(j); + if (extra_t != phi_type && extra_t->higher_equal_speculative(phi_type)) { + types.insert_sorted(extra_t); + } + } + in = next; + } + } + const Type **flds = (const Type **)(phase->C->type_arena()->AmallocWords(types.length()*sizeof(Type*))); + for (int i = 0; i < types.length(); ++i) { + flds[i] = types.at(i); + } + return TypeTuple::make(types.length(), flds); +} + Node* PhiNode::clone_through_phi(Node* root_phi, const Type* t, uint c, PhaseIterGVN* igvn) { Node_Stack stack(1); VectorSet visited; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/cfgnode.hpp openjdk-21-21.0.2+13/src/hotspot/share/opto/cfgnode.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/cfgnode.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/cfgnode.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -266,6 +266,8 @@ #else //ASSERT void verify_adr_type(bool recursive = false) const {} #endif //ASSERT + + const TypeTuple* collect_types(PhaseGVN* phase) const; }; //------------------------------GotoNode--------------------------------------- diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/compile.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/compile.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/compile.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/compile.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2230,6 +2230,8 @@ process_for_unstable_if_traps(igvn); + if (failing()) return; + inline_incrementally(igvn); print_method(PHASE_INCREMENTAL_INLINE, 2); @@ -2240,6 +2242,8 @@ // Inline valueOf() methods now. inline_boxing_calls(igvn); + if (failing()) return; + if (AlwaysIncrementalInline) { inline_incrementally(igvn); } @@ -2255,16 +2259,20 @@ // CastPP nodes. remove_speculative_types(igvn); + if (failing()) return; + // No more new expensive nodes will be added to the list from here // so keep only the actual candidates for optimizations. cleanup_expensive_nodes(igvn); + if (failing()) return; + assert(EnableVectorSupport || !has_vbox_nodes(), "sanity"); if (EnableVectorSupport && has_vbox_nodes()) { TracePhase tp("", &timers[_t_vector]); PhaseVector pv(igvn); pv.optimize_vector_boxes(); - + if (failing()) return; print_method(PHASE_ITER_GVN_AFTER_VECTOR, 2); } assert(!has_vbox_nodes(), "sanity"); @@ -2284,6 +2292,8 @@ // safepoints remove_root_to_sfpts_edges(igvn); + if (failing()) return; + // Perform escape analysis if (do_escape_analysis() && ConnectionGraph::has_candidates(this)) { if (has_loops()) { @@ -2393,6 +2403,8 @@ process_for_post_loop_opts_igvn(igvn); + if (failing()) return; + #ifdef ASSERT bs->verify_gc_barriers(this, BarrierSetC2::BeforeMacroExpand); #endif @@ -2431,6 +2443,7 @@ // More opportunities to optimize virtual and MH calls. // Though it's maybe too late to perform inlining, strength-reducing them to direct calls is still an option. process_late_inline_calls_no_inline(igvn); + if (failing()) return; } } // (End scope of igvn; run destructor if necessary for asserts.) @@ -4907,6 +4920,7 @@ igvn.remove_speculative_types(); if (modified > 0) { igvn.optimize(); + if (failing()) return; } #ifdef ASSERT // Verify that after the IGVN is over no speculative type has resurfaced diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/graphKit.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/graphKit.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/graphKit.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/graphKit.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -3728,7 +3728,10 @@ //-------------------------------new_array------------------------------------- // helper for both newarray and anewarray // The 'length' parameter is (obviously) the length of the array. -// See comments on new_instance for the meaning of the other arguments. +// The optional arguments are for specialized use by intrinsics: +// - If 'return_size_val', report the non-padded array size (sum of header size +// and array body) to the caller. +// - deoptimize_on_exception controls how Java exceptions are handled (rethrow vs deoptimize) Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable) Node* length, // number of array elements int nargs, // number of arguments to push back for uncommon trap @@ -3779,25 +3782,21 @@ // The rounding mask is strength-reduced, if possible. int round_mask = MinObjAlignmentInBytes - 1; Node* header_size = nullptr; - int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE); // (T_BYTE has the weakest alignment and size restrictions...) if (layout_is_con) { int hsize = Klass::layout_helper_header_size(layout_con); int eshift = Klass::layout_helper_log2_element_size(layout_con); - BasicType etype = Klass::layout_helper_element_type(layout_con); if ((round_mask & ~right_n_bits(eshift)) == 0) round_mask = 0; // strength-reduce it if it goes away completely assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded"); + int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE); assert(header_size_min <= hsize, "generic minimum is smallest"); - header_size_min = hsize; - header_size = intcon(hsize + round_mask); + header_size = intcon(hsize); } else { Node* hss = intcon(Klass::_lh_header_size_shift); Node* hsm = intcon(Klass::_lh_header_size_mask); - Node* hsize = _gvn.transform( new URShiftINode(layout_val, hss) ); - hsize = _gvn.transform( new AndINode(hsize, hsm) ); - Node* mask = intcon(round_mask); - header_size = _gvn.transform( new AddINode(hsize, mask) ); + header_size = _gvn.transform(new URShiftINode(layout_val, hss)); + header_size = _gvn.transform(new AndINode(header_size, hsm)); } Node* elem_shift = nullptr; @@ -3849,24 +3848,29 @@ } #endif - // Combine header size (plus rounding) and body size. Then round down. - // This computation cannot overflow, because it is used only in two - // places, one where the length is sharply limited, and the other - // after a successful allocation. + // Combine header size and body size for the array copy part, then align (if + // necessary) for the allocation part. This computation cannot overflow, + // because it is used only in two places, one where the length is sharply + // limited, and the other after a successful allocation. Node* abody = lengthx; - if (elem_shift != nullptr) - abody = _gvn.transform( new LShiftXNode(lengthx, elem_shift) ); - Node* size = _gvn.transform( new AddXNode(headerx, abody) ); - if (round_mask != 0) { - Node* mask = MakeConX(~round_mask); - size = _gvn.transform( new AndXNode(size, mask) ); + if (elem_shift != nullptr) { + abody = _gvn.transform(new LShiftXNode(lengthx, elem_shift)); } - // else if round_mask == 0, the size computation is self-rounding + Node* non_rounded_size = _gvn.transform(new AddXNode(headerx, abody)); if (return_size_val != nullptr) { // This is the size - (*return_size_val) = size; + (*return_size_val) = non_rounded_size; + } + + Node* size = non_rounded_size; + if (round_mask != 0) { + Node* mask1 = MakeConX(round_mask); + size = _gvn.transform(new AddXNode(size, mask1)); + Node* mask2 = MakeConX(~round_mask); + size = _gvn.transform(new AndXNode(size, mask2)); } + // else if round_mask == 0, the size computation is self-rounding // Now generate allocation code diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/graphKit.hpp openjdk-21-21.0.2+13/src/hotspot/share/opto/graphKit.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/graphKit.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/graphKit.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -82,7 +82,8 @@ #ifdef ASSERT ~GraphKit() { - assert(!has_exceptions(), "user must call transfer_exceptions_into_jvms"); + assert(failing() || !has_exceptions(), + "unless compilation failed, user must call transfer_exceptions_into_jvms"); } #endif diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/ifnode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/ifnode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/ifnode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/ifnode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1833,6 +1833,46 @@ // then we are guaranteed to fail, so just start interpreting there. // We 'expand' the top 3 range checks to include all post-dominating // checks. + // + // Example: + // a[i+x] // (1) 1 < x < 6 + // a[i+3] // (2) + // a[i+4] // (3) + // a[i+6] // max = max of all constants + // a[i+2] + // a[i+1] // min = min of all constants + // + // If x < 3: + // (1) a[i+x]: Leave unchanged + // (2) a[i+3]: Replace with a[i+max] = a[i+6]: i+x < i+3 <= i+6 -> (2) is covered + // (3) a[i+4]: Replace with a[i+min] = a[i+1]: i+1 < i+4 <= i+6 -> (3) and all following checks are covered + // Remove all other a[i+c] checks + // + // If x >= 3: + // (1) a[i+x]: Leave unchanged + // (2) a[i+3]: Replace with a[i+min] = a[i+1]: i+1 < i+3 <= i+x -> (2) is covered + // (3) a[i+4]: Replace with a[i+max] = a[i+6]: i+1 < i+4 <= i+6 -> (3) and all following checks are covered + // Remove all other a[i+c] checks + // + // We only need the top 2 range checks if x is the min or max of all constants. + // + // This, however, only works if the interval [i+min,i+max] is not larger than max_int (i.e. abs(max - min) < max_int): + // The theoretical max size of an array is max_int with: + // - Valid index space: [0,max_int-1] + // - Invalid index space: [max_int,-1] // max_int, min_int, min_int - 1 ..., -1 + // + // The size of the consecutive valid index space is smaller than the size of the consecutive invalid index space. + // If we choose min and max in such a way that: + // - abs(max - min) < max_int + // - i+max and i+min are inside the valid index space + // then all indices [i+min,i+max] must be in the valid index space. Otherwise, the invalid index space must be + // smaller than the valid index space which is never the case for any array size. + // + // Choosing a smaller array size only makes the valid index space smaller and the invalid index space larger and + // the argument above still holds. + // + // Note that the same optimization with the same maximal accepted interval size can also be found in C1. + const jlong maximum_number_of_min_max_interval_indices = (jlong)max_jint; // The top 3 range checks seen const int NRC = 3; @@ -1867,13 +1907,18 @@ found_immediate_dominator = true; break; } - // Gather expanded bounds - off_lo = MIN2(off_lo,offset2); - off_hi = MAX2(off_hi,offset2); - // Record top NRC range checks - prev_checks[nb_checks%NRC].ctl = prev_dom; - prev_checks[nb_checks%NRC].off = offset2; - nb_checks++; + + // "x - y" -> must add one to the difference for number of elements in [x,y] + const jlong diff = (jlong)MIN2(offset2, off_lo) - (jlong)MAX2(offset2, off_hi); + if (ABS(diff) < maximum_number_of_min_max_interval_indices) { + // Gather expanded bounds + off_lo = MIN2(off_lo, offset2); + off_hi = MAX2(off_hi, offset2); + // Record top NRC range checks + prev_checks[nb_checks % NRC].ctl = prev_dom; + prev_checks[nb_checks % NRC].off = offset2; + nb_checks++; + } } } prev_dom = dom; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/library_call.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/library_call.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/library_call.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/library_call.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2864,6 +2864,7 @@ if (!DoJVMTIVirtualThreadTransitions) { return true; } + Node* vt_oop = _gvn.transform(must_be_not_null(argument(0), true)); // VirtualThread this argument IdealKit ideal(this); Node* ONE = ideal.ConI(1); @@ -2872,16 +2873,13 @@ Node* notify_jvmti_enabled = ideal.load(ideal.ctrl(), addr, TypeInt::BOOL, T_BOOLEAN, Compile::AliasIdxRaw); ideal.if_then(notify_jvmti_enabled, BoolTest::eq, ONE); { + sync_kit(ideal); // if notifyJvmti enabled then make a call to the given SharedRuntime function const TypeFunc* tf = OptoRuntime::notify_jvmti_vthread_Type(); - Node* vt_oop = _gvn.transform(must_be_not_null(argument(0), true)); // VirtualThread this argument - - sync_kit(ideal); make_runtime_call(RC_NO_LEAF, tf, funcAddr, funcName, TypePtr::BOTTOM, vt_oop, hide); ideal.sync_kit(this); } ideal.else_(); { // set hide value to the VTMS transition bit in current JavaThread and VirtualThread object - Node* vt_oop = _gvn.transform(argument(0)); // this argument - VirtualThread oop Node* thread = ideal.thread(); Node* jt_addr = basic_plus_adr(thread, in_bytes(JavaThread::is_in_VTMS_transition_offset())); Node* vt_addr = basic_plus_adr(vt_oop, java_lang_Thread::is_in_VTMS_transition_offset()); @@ -4994,8 +4992,8 @@ PreserveJVMState pjvms(this); set_control(array_ctl); Node* obj_length = load_array_length(obj); - Node* obj_size = nullptr; - Node* alloc_obj = new_array(obj_klass, obj_length, 0, &obj_size, /*deoptimize_on_exception=*/true); + Node* array_size = nullptr; // Size of the array without object alignment padding. + Node* alloc_obj = new_array(obj_klass, obj_length, 0, &array_size, /*deoptimize_on_exception=*/true); BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); if (bs->array_copy_requires_gc_barriers(true, T_OBJECT, true, false, BarrierSetC2::Parsing)) { @@ -5028,7 +5026,7 @@ // the object.) if (!stopped()) { - copy_to_clone(obj, alloc_obj, obj_size, true); + copy_to_clone(obj, alloc_obj, array_size, true); // Present the results of the copy. result_reg->init_req(_array_path, control()); @@ -5068,7 +5066,7 @@ if (!stopped()) { // It's an instance, and it passed the slow-path tests. PreserveJVMState pjvms(this); - Node* obj_size = nullptr; + Node* obj_size = nullptr; // Total object size, including object alignment padding. // Need to deoptimize on exception from allocation since Object.clone intrinsic // is reexecuted if deoptimization occurs and there could be problems when merging // exception state between multiple Object.clone versions (reexecute=true vs reexecute=false). diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/loopPredicate.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/loopPredicate.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/loopPredicate.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/loopPredicate.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1035,9 +1035,10 @@ // Check if (scale * max_idx_expr) may overflow const TypeInt* scale_type = TypeInt::make(scale); MulINode* mul = new MulINode(max_idx_expr, con_scale); - idx_type = (TypeInt*)mul->mul_ring(idx_type, scale_type); - if (overflow || TypeInt::INT->higher_equal(idx_type)) { + + if (overflow || MulINode::does_overflow(idx_type, scale_type)) { // May overflow + idx_type = TypeInt::INT; mul->destruct(&_igvn); if (!overflow) { max_idx_expr = new ConvI2LNode(max_idx_expr); @@ -1050,6 +1051,7 @@ } else { // No overflow possible max_idx_expr = mul; + idx_type = (TypeInt*)mul->mul_ring(idx_type, scale_type); } register_new_node(max_idx_expr, ctrl); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/loopTransform.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/loopTransform.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/loopTransform.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/loopTransform.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1965,6 +1965,9 @@ post_head->set_normal_loop(); post_head->set_post_loop(main_head); + // clone_loop() above changes the exit projection + main_exit = outer_main_end->proj_out(false); + // Reduce the post-loop trip count. CountedLoopEndNode* post_end = old_new[main_end->_idx]->as_CountedLoopEnd(); post_end->_prob = PROB_FAIR; @@ -3707,7 +3710,7 @@ void IdealLoopTree::collect_loop_core_nodes(PhaseIdealLoop* phase, Unique_Node_List& wq) const { uint before = wq.size(); wq.push(_head->in(LoopNode::LoopBackControl)); - for (uint i = 0; i < wq.size(); ++i) { + for (uint i = before; i < wq.size(); ++i) { Node* n = wq.at(i); for (uint j = 0; j < n->req(); ++j) { Node* in = n->in(j); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/loopnode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/loopnode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/loopnode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/loopnode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -493,19 +493,19 @@ return phi; } -static int check_stride_overflow(jlong stride_con, const TypeInteger* limit_t, BasicType bt) { - if (stride_con > 0) { - if (limit_t->lo_as_long() > (max_signed_integer(bt) - stride_con)) { +static int check_stride_overflow(jlong final_correction, const TypeInteger* limit_t, BasicType bt) { + if (final_correction > 0) { + if (limit_t->lo_as_long() > (max_signed_integer(bt) - final_correction)) { return -1; } - if (limit_t->hi_as_long() > (max_signed_integer(bt) - stride_con)) { + if (limit_t->hi_as_long() > (max_signed_integer(bt) - final_correction)) { return 1; } } else { - if (limit_t->hi_as_long() < (min_signed_integer(bt) - stride_con)) { + if (limit_t->hi_as_long() < (min_signed_integer(bt) - final_correction)) { return -1; } - if (limit_t->lo_as_long() < (min_signed_integer(bt) - stride_con)) { + if (limit_t->lo_as_long() < (min_signed_integer(bt) - final_correction)) { return 1; } } @@ -767,7 +767,7 @@ // // inner_incr := AddI(inner_phi, intcon(stride)) // inner_incr = inner_phi + stride; // if (inner_incr < inner_iters_actual) { -// ... use phi=>(outer_phi+inner_phi) and incr=>(outer_phi+inner_incr) ... +// ... use phi=>(outer_phi+inner_phi) ... // continue; // } // else break; @@ -977,10 +977,6 @@ // loop iv phi Node* iv_add = loop_nest_replace_iv(phi, inner_phi, outer_phi, head, bt); - // Replace inner loop long iv incr with inner loop int incr + outer - // loop iv phi - loop_nest_replace_iv(incr, inner_incr, outer_phi, head, bt); - set_subtree_ctrl(inner_iters_actual_int, body_populated); LoopNode* inner_head = create_inner_head(loop, head, exit_test); @@ -1029,7 +1025,7 @@ // back_control: fallthrough; // else // inner_exit_branch: break; //exit_branch->clone() - // ... use phi=>(outer_phi+inner_phi) and incr=>(outer_phi+inner_incr) ... + // ... use phi=>(outer_phi+inner_phi) ... // inner_phi = inner_phi + stride; // inner_incr // } // outer_exit_test: //exit_test->clone(), in(0):=inner_exit_branch @@ -1749,50 +1745,205 @@ C->print_method(PHASE_BEFORE_CLOOPS, 3); // =================================================== - // Generate loop limit check to avoid integer overflow - // in cases like next (cyclic loops): + // We can only convert this loop to a counted loop if we can guarantee that the iv phi will never overflow at runtime. + // This is an implicit assumption taken by some loop optimizations. We therefore must ensure this property at all cost. + // At this point, we've already excluded some trivial cases where an overflow could have been proven statically. + // But even though we cannot prove that an overflow will *not* happen, we still want to speculatively convert this loop + // to a counted loop. This can be achieved by adding additional iv phi overflow checks before the loop. If they fail, + // we trap and resume execution before the loop without having executed any iteration of the loop, yet. // - // for (i=0; i <= max_jint; i++) {} - // for (i=0; i < max_jint; i+=2) {} + // These additional iv phi overflow checks can be inserted as Loop Limit Check Predicates above the Loop Limit Check + // Parse Predicate which captures a JVM state just before the entry of the loop. If there is no such Parse Predicate, + // we cannot generate a Loop Limit Check Predicate and thus cannot speculatively convert the loop to a counted loop. // + // In the following, we only focus on int loops with stride > 0 to keep things simple. The argumentation and proof + // for stride < 0 is analogously. For long loops, we would replace max_int with max_long. // - // Limit check predicate depends on the loop test: // - // for(;i != limit; i++) --> limit <= (max_jint) - // for(;i < limit; i+=stride) --> limit <= (max_jint - stride + 1) - // for(;i <= limit; i+=stride) --> limit <= (max_jint - stride ) + // The loop to be converted does not always need to have the often used shape: // + // i = init + // i = init loop: + // do { ... + // // ... equivalent i+=stride + // i+=stride <==> if (i < limit) + // } while (i < limit); goto loop + // exit: + // ... + // + // where the loop exit check uses the post-incremented iv phi and a '<'-operator. + // + // We could also have '<='-operator (or '>='-operator for negative strides) or use the pre-incremented iv phi value + // in the loop exit check: + // + // i = init + // loop: + // ... + // if (i <= limit) + // i+=stride + // goto loop + // exit: + // ... + // + // Let's define the following terms: + // - iv_pre_i: The pre-incremented iv phi before the i-th iteration. + // - iv_post_i: The post-incremented iv phi after the i-th iteration. + // + // The iv_pre_i and iv_post_i have the following relation: + // iv_pre_i + stride = iv_post_i + // + // When converting a loop to a counted loop, we want to have a canonicalized loop exit check of the form: + // iv_post_i < adjusted_limit + // + // If that is not the case, we need to canonicalize the loop exit check by using different values for adjusted_limit: + // (LE1) iv_post_i < limit: Already canonicalized. We can directly use limit as adjusted_limit. + // -> adjusted_limit = limit. + // (LE2) iv_post_i <= limit: + // iv_post_i < limit + 1 + // -> adjusted limit = limit + 1 + // (LE3) iv_pre_i < limit: + // iv_pre_i + stride < limit + stride + // iv_post_i < limit + stride + // -> adjusted_limit = limit + stride + // (LE4) iv_pre_i <= limit: + // iv_pre_i < limit + 1 + // iv_pre_i + stride < limit + stride + 1 + // iv_post_i < limit + stride + 1 + // -> adjusted_limit = limit + stride + 1 + // + // Note that: + // (AL) limit <= adjusted_limit. + // + // The following loop invariant has to hold for counted loops with n iterations (i.e. loop exit check true after n-th + // loop iteration) and a canonicalized loop exit check to guarantee that no iv_post_i over- or underflows: + // (INV) For i = 1..n, min_int <= iv_post_i <= max_int + // + // To prove (INV), we require the following two conditions/assumptions: + // (i): adjusted_limit - 1 + stride <= max_int + // (ii): init < limit + // + // If we can prove (INV), we know that there can be no over- or underflow of any iv phi value. We prove (INV) by + // induction by assuming (i) and (ii). + // + // Proof by Induction + // ------------------ + // > Base case (i = 1): We show that (INV) holds after the first iteration: + // min_int <= iv_post_1 = init + stride <= max_int + // Proof: + // First, we note that (ii) implies + // (iii) init <= limit - 1 + // max_int >= adjusted_limit - 1 + stride [using (i)] + // >= limit - 1 + stride [using (AL)] + // >= init + stride [using (iii)] + // >= min_int [using stride > 0, no underflow] + // Thus, no overflow happens after the first iteration and (INV) holds for i = 1. + // + // Note that to prove the base case we need (i) and (ii). + // + // > Induction Hypothesis (i = j, j > 1): Assume that (INV) holds after the j-th iteration: + // min_int <= iv_post_j <= max_int + // > Step case (i = j + 1): We show that (INV) also holds after the j+1-th iteration: + // min_int <= iv_post_{j+1} = iv_post_j + stride <= max_int + // Proof: + // If iv_post_j >= adjusted_limit: + // We exit the loop after the j-th iteration, and we don't execute the j+1-th iteration anymore. Thus, there is + // also no iv_{j+1}. Since (INV) holds for iv_j, there is nothing left to prove. + // If iv_post_j < adjusted_limit: + // First, we note that: + // (iv) iv_post_j <= adjusted_limit - 1 + // max_int >= adjusted_limit - 1 + stride [using (i)] + // >= iv_post_j + stride [using (iv)] + // >= min_int [using stride > 0, no underflow] + // + // Note that to prove the step case we only need (i). + // + // Thus, by assuming (i) and (ii), we proved (INV). + // + // + // It is therefore enough to add the following two Loop Limit Check Predicates to check assumptions (i) and (ii): + // + // (1) Loop Limit Check Predicate for (i): + // Using (i): adjusted_limit - 1 + stride <= max_int + // + // This condition is now restated to use limit instead of adjusted_limit: + // + // To prevent an overflow of adjusted_limit -1 + stride itself, we rewrite this check to + // max_int - stride + 1 >= adjusted_limit + // We can merge the two constants into + // canonicalized_correction = stride - 1 + // which gives us + // max_int - canonicalized_correction >= adjusted_limit + // + // To directly use limit instead of adjusted_limit in the predicate condition, we split adjusted_limit into: + // adjusted_limit = limit + limit_correction + // Since stride > 0 and limit_correction <= stride + 1, we can restate this with no over- or underflow into: + // max_int - canonicalized_correction - limit_correction >= limit + // Since canonicalized_correction and limit_correction are both constants, we can replace them with a new constant: + // final_correction = canonicalized_correction + limit_correction + // which gives us: + // + // Final predicate condition: + // max_int - final_correction >= limit + // + // (2) Loop Limit Check Predicate for (ii): + // Using (ii): init < limit + // + // This Loop Limit Check Predicate is not required if we can prove at compile time that either: + // (2.1) type(init) < type(limit) + // In this case, we know: + // all possible values of init < all possible values of limit + // and we can skip the predicate. + // + // (2.2) init < limit is already checked before (i.e. found as a dominating check) + // In this case, we do not need to re-check the condition and can skip the predicate. + // This is often found for while- and for-loops which have the following shape: + // + // if (init < limit) { // Dominating test. Do not need the Loop Limit Check Predicate below. + // i = init; + // if (init >= limit) { trap(); } // Here we would insert the Loop Limit Check Predicate + // do { + // i += stride; + // } while (i < limit); + // } + // + // (2.3) init + stride <= max_int + // In this case, there is no overflow of the iv phi after the first loop iteration. + // In the proof of the base case above we showed that init + stride <= max_int by using assumption (ii): + // init < limit + // In the proof of the step case above, we did not need (ii) anymore. Therefore, if we already know at + // compile time that init + stride <= max_int then we have trivially proven the base case and that + // there is no overflow of the iv phi after the first iteration. In this case, we don't need to check (ii) + // again and can skip the predicate. + + + // Accounting for (LE3) and (LE4) where we use pre-incremented phis in the loop exit check. + const jlong limit_correction_for_pre_iv_exit_check = (phi_incr != nullptr) ? stride_con : 0; + + // Accounting for (LE2) and (LE4) where we use <= or >= in the loop exit check. + const bool includes_limit = (bt == BoolTest::le || bt == BoolTest::ge); + const jlong limit_correction_for_le_ge_exit_check = (includes_limit ? (stride_con > 0 ? 1 : -1) : 0); + + const jlong limit_correction = limit_correction_for_pre_iv_exit_check + limit_correction_for_le_ge_exit_check; + const jlong canonicalized_correction = stride_con + (stride_con > 0 ? -1 : 1); + const jlong final_correction = canonicalized_correction + limit_correction; - // Check if limit is excluded to do more precise int overflow check. - bool incl_limit = (bt == BoolTest::le || bt == BoolTest::ge); - jlong stride_m = stride_con - (incl_limit ? 0 : (stride_con > 0 ? 1 : -1)); - - // If compare points directly to the phi we need to adjust - // the compare so that it points to the incr. Limit have - // to be adjusted to keep trip count the same and the - // adjusted limit should be checked for int overflow. - Node* adjusted_limit = limit; - if (phi_incr != nullptr) { - stride_m += stride_con; - } - - Node *init_control = x->in(LoopNode::EntryControl); + int sov = check_stride_overflow(final_correction, limit_t, iv_bt); + Node* init_control = x->in(LoopNode::EntryControl); - int sov = check_stride_overflow(stride_m, limit_t, iv_bt); // If sov==0, limit's type always satisfies the condition, for // example, when it is an array length. if (sov != 0) { if (sov < 0) { return false; // Bailout: integer overflow is certain. } + // (1) Loop Limit Check Predicate is required because we could not statically prove that + // limit + final_correction = adjusted_limit - 1 + stride <= max_int assert(!x->as_Loop()->is_loop_nest_inner_loop(), "loop was transformed"); - // Generate loop's limit check. - // Loop limit check predicate should be near the loop. if (!ParsePredicates::is_loop_limit_check_predicate_proj(init_control)) { - // The limit check predicate is not generated if this method trapped here before. + // The Loop Limit Check Parse Predicate is not generated if this method trapped here before. #ifdef ASSERT if (TraceLoopLimitCheck) { - tty->print("missing loop limit check:"); + tty->print("Missing Loop Limit Check Parse Predicate:"); loop->dump_head(); x->dump(1); } @@ -1811,65 +1962,79 @@ Node* bol; if (stride_con > 0) { - cmp_limit = CmpNode::make(limit, _igvn.integercon(max_signed_integer(iv_bt) - stride_m, iv_bt), iv_bt); + cmp_limit = CmpNode::make(limit, _igvn.integercon(max_signed_integer(iv_bt) - final_correction, iv_bt), iv_bt); bol = new BoolNode(cmp_limit, BoolTest::le); } else { - cmp_limit = CmpNode::make(limit, _igvn.integercon(min_signed_integer(iv_bt) - stride_m, iv_bt), iv_bt); + cmp_limit = CmpNode::make(limit, _igvn.integercon(min_signed_integer(iv_bt) - final_correction, iv_bt), iv_bt); bol = new BoolNode(cmp_limit, BoolTest::ge); } insert_loop_limit_check_predicate(loop_limit_check_parse_predicate_proj, cmp_limit, bol); } - // Now we need to canonicalize loop condition. - if (bt == BoolTest::ne) { - assert(stride_con == 1 || stride_con == -1, "simple increment only"); - if (stride_con > 0 && init_t->hi_as_long() < limit_t->lo_as_long()) { - // 'ne' can be replaced with 'lt' only when init < limit. - bt = BoolTest::lt; - } else if (stride_con < 0 && init_t->lo_as_long() > limit_t->hi_as_long()) { - // 'ne' can be replaced with 'gt' only when init > limit. - bt = BoolTest::gt; - } else { - if (!ParsePredicates::is_loop_limit_check_predicate_proj(init_control)) { - // The limit check predicate is not generated if this method trapped here before. + // (2.3) + const bool init_plus_stride_could_overflow = + (stride_con > 0 && init_t->hi_as_long() > max_signed_integer(iv_bt) - stride_con) || + (stride_con < 0 && init_t->lo_as_long() < min_signed_integer(iv_bt) - stride_con); + // (2.1) + const bool init_gte_limit = (stride_con > 0 && init_t->hi_as_long() >= limit_t->lo_as_long()) || + (stride_con < 0 && init_t->lo_as_long() <= limit_t->hi_as_long()); + + if (init_gte_limit && // (2.1) + ((bt == BoolTest::ne || init_plus_stride_could_overflow) && // (2.3) + !has_dominating_loop_limit_check(init_trip, limit, stride_con, iv_bt, init_control))) { // (2.2) + // (2) Iteration Loop Limit Check Predicate is required because neither (2.1), (2.2), nor (2.3) holds. + // We use the following condition: + // - stride > 0: init < limit + // - stride < 0: init > limit + // + // This predicate is always required if we have a non-equal-operator in the loop exit check (where stride = 1 is + // a requirement). We transform the loop exit check by using a less-than-operator. By doing so, we must always + // check that init < limit. Otherwise, we could have a different number of iterations at runtime. + + if (!ParsePredicates::is_loop_limit_check_predicate_proj(init_control)) { + // The Loop Limit Check Parse Predicate is not generated if this method trapped here before. #ifdef ASSERT - if (TraceLoopLimitCheck) { - tty->print("missing loop limit check:"); - loop->dump_head(); - x->dump(1); - } -#endif - return false; + if (TraceLoopLimitCheck) { + tty->print("Missing Loop Limit Check Parse Predicate:"); + loop->dump_head(); + x->dump(1); } - ParsePredicateSuccessProj* loop_limit_check_parse_predicate_proj = init_control->as_IfTrue(); - ParsePredicateNode* parse_predicate = init_control->in(0)->as_ParsePredicate(); +#endif + return false; + } + ParsePredicateSuccessProj* loop_limit_check_parse_predicate_proj = init_control->as_IfTrue(); + ParsePredicateNode* parse_predicate = init_control->in(0)->as_ParsePredicate(); - if (!is_dominator(get_ctrl(limit), parse_predicate->in(0)) || - !is_dominator(get_ctrl(init_trip), parse_predicate->in(0))) { - return false; - } + if (!is_dominator(get_ctrl(limit), parse_predicate->in(0)) || + !is_dominator(get_ctrl(init_trip), parse_predicate->in(0))) { + return false; + } - Node* cmp_limit; - Node* bol; + Node* cmp_limit; + Node* bol; - if (stride_con > 0) { - cmp_limit = CmpNode::make(init_trip, limit, iv_bt); - bol = new BoolNode(cmp_limit, BoolTest::lt); - } else { - cmp_limit = CmpNode::make(init_trip, limit, iv_bt); - bol = new BoolNode(cmp_limit, BoolTest::gt); - } + if (stride_con > 0) { + cmp_limit = CmpNode::make(init_trip, limit, iv_bt); + bol = new BoolNode(cmp_limit, BoolTest::lt); + } else { + cmp_limit = CmpNode::make(init_trip, limit, iv_bt); + bol = new BoolNode(cmp_limit, BoolTest::gt); + } - insert_loop_limit_check_predicate(loop_limit_check_parse_predicate_proj, cmp_limit, bol); + insert_loop_limit_check_predicate(loop_limit_check_parse_predicate_proj, cmp_limit, bol); + } - if (stride_con > 0) { - // 'ne' can be replaced with 'lt' only when init < limit. - bt = BoolTest::lt; - } else if (stride_con < 0) { - // 'ne' can be replaced with 'gt' only when init > limit. - bt = BoolTest::gt; - } + if (bt == BoolTest::ne) { + // Now we need to canonicalize the loop condition if it is 'ne'. + assert(stride_con == 1 || stride_con == -1, "simple increment only - checked before"); + if (stride_con > 0) { + // 'ne' can be replaced with 'lt' only when init < limit. This is ensured by the inserted predicate above. + bt = BoolTest::lt; + } else { + assert(stride_con < 0, "must be"); + // 'ne' can be replaced with 'gt' only when init > limit. This is ensured by the inserted predicate above. + bt = BoolTest::gt; } } @@ -1914,6 +2079,7 @@ } #endif + Node* adjusted_limit = limit; if (phi_incr != nullptr) { // If compare points directly to the phi we need to adjust // the compare so that it points to the incr. Limit have @@ -1927,7 +2093,7 @@ adjusted_limit = gvn->transform(AddNode::make(limit, stride, iv_bt)); } - if (incl_limit) { + if (includes_limit) { // The limit check guaranties that 'limit <= (max_jint - stride)' so // we can convert 'i <= limit' to 'i < limit+1' since stride != 0. // @@ -2108,6 +2274,37 @@ return true; } +// Check if there is a dominating loop limit check of the form 'init < limit' starting at the loop entry. +// If there is one, then we do not need to create an additional Loop Limit Check Predicate. +bool PhaseIdealLoop::has_dominating_loop_limit_check(Node* init_trip, Node* limit, const jlong stride_con, + const BasicType iv_bt, Node* loop_entry) { + // Eagerly call transform() on the Cmp and Bool node to common them up if possible. This is required in order to + // successfully find a dominated test with the If node below. + Node* cmp_limit; + Node* bol; + if (stride_con > 0) { + cmp_limit = _igvn.transform(CmpNode::make(init_trip, limit, iv_bt)); + bol = _igvn.transform(new BoolNode(cmp_limit, BoolTest::lt)); + } else { + cmp_limit = _igvn.transform(CmpNode::make(init_trip, limit, iv_bt)); + bol = _igvn.transform(new BoolNode(cmp_limit, BoolTest::gt)); + } + + // Check if there is already a dominating init < limit check. If so, we do not need a Loop Limit Check Predicate. + IfNode* iff = new IfNode(loop_entry, bol, PROB_MIN, COUNT_UNKNOWN); + // Also add fake IfProj nodes in order to call transform() on the newly created IfNode. + IfFalseNode* if_false = new IfFalseNode(iff); + IfTrueNode* if_true = new IfTrueNode(iff); + Node* dominated_iff = _igvn.transform(iff); + // ConI node? Found dominating test (IfNode::dominated_by() returns a ConI node). + const bool found_dominating_test = dominated_iff != nullptr && dominated_iff->is_ConI(); + + // Kill the If with its projections again in the next IGVN round by cutting it off from the graph. + _igvn.replace_input_of(iff, 0, C->top()); + _igvn.replace_input_of(iff, 1, C->top()); + return found_dominating_test; +} + //----------------------exact_limit------------------------------------------- Node* PhaseIdealLoop::exact_limit( IdealLoopTree *loop ) { assert(loop->_head->is_CountedLoop(), ""); @@ -4448,6 +4645,7 @@ NOT_PRODUCT( C->verify_graph_edges(); ) worklist.push(C->top()); build_loop_late( visited, worklist, nstack ); + if (C->failing()) { return; } if (_verify_only) { C->restore_major_progress(old_progress); @@ -4702,6 +4900,7 @@ bool success = true; PhaseIdealLoop phase_verify(_igvn, this); + if (C->failing()) return; // Verify ctrl and idom of every node. success &= verify_idom_and_nodes(C->root(), &phase_verify); @@ -5954,6 +6153,7 @@ } else { // All of n's children have been processed, complete post-processing. build_loop_late_post(n); + if (C->failing()) { return; } if (nstack.is_empty()) { // Finished all nodes on stack. // Process next node on the worklist. @@ -6100,13 +6300,15 @@ Node *legal = LCA; // Walk 'legal' up the IDOM chain Node *least = legal; // Best legal position so far while( early != legal ) { // While not at earliest legal -#ifdef ASSERT if (legal->is_Start() && !early->is_Root()) { +#ifdef ASSERT // Bad graph. Print idom path and fail. dump_bad_graph("Bad graph detected in build_loop_late", n, early, LCA); assert(false, "Bad graph detected in build_loop_late"); - } #endif + C->record_method_not_compilable("Bad graph detected in build_loop_late"); + return; + } // Find least loop nesting depth legal = idom(legal); // Bump up the IDOM tree // Check for lower nesting depth diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/loopnode.hpp openjdk-21-21.0.2+13/src/hotspot/share/opto/loopnode.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/loopnode.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/loopnode.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -1206,7 +1206,7 @@ if (!C->failing()) { // Cleanup any modified bits igvn.optimize(); - + if (C->failing()) { return; } v.log_loop_tree(); } } @@ -1361,6 +1361,8 @@ void rewire_cloned_nodes_to_ctrl(const ProjNode* old_ctrl, Node* new_ctrl, const Node_List& nodes_with_same_ctrl, const Dict& old_new_mapping); void rewire_inputs_of_clones_to_clones(Node* new_ctrl, Node* clone, const Dict& old_new_mapping, const Node* next); + bool has_dominating_loop_limit_check(Node* init_trip, Node* limit, jlong stride_con, BasicType iv_bt, + Node* loop_entry); public: void register_control(Node* n, IdealLoopTree *loop, Node* pred, bool update_body = true); @@ -1549,7 +1551,7 @@ Node *find_use_block( Node *use, Node *def, Node *old_false, Node *new_false, Node *old_true, Node *new_true ); void handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true ); bool split_up( Node *n, Node *blk1, Node *blk2 ); - void sink_use( Node *use, Node *post_loop ); + Node* place_outside_loop(Node* useblock, IdealLoopTree* loop) const; Node* try_move_store_before_loop(Node* n, Node *n_ctrl); void try_move_store_after_loop(Node* n); @@ -1737,6 +1739,8 @@ bool clone_cmp_loadklass_down(Node* n, const Node* blk1, const Node* blk2); bool at_relevant_ctrl(Node* n, const Node* blk1, const Node* blk2); + + void update_addp_chain_base(Node* x, Node* old_base, Node* new_base); }; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/loopopts.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/loopopts.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/loopopts.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/loopopts.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1677,9 +1677,10 @@ assert(!n_loop->is_member(get_loop(x_ctrl)), "should have moved out of loop"); register_new_node(x, x_ctrl); - // Chain of AddP: (AddP base (AddP base )) must keep the same base after sinking so: - // 1- We don't add a CastPP here when the first one is sunk so if the second one is not, their bases remain - // the same. + // Chain of AddP nodes: (AddP base (AddP base (AddP base ))) + // All AddP nodes must keep the same base after sinking so: + // 1- We don't add a CastPP here until the last one of the chain is sunk: if part of the chain is not sunk, + // their bases remain the same. // (see 2- below) assert(!x->is_AddP() || !x->in(AddPNode::Address)->is_AddP() || x->in(AddPNode::Address)->in(AddPNode::Base) == x->in(AddPNode::Base) || @@ -1693,21 +1694,22 @@ Node* in = x->in(k); if (in != nullptr && n_loop->is_member(get_loop(get_ctrl(in)))) { const Type* in_t = _igvn.type(in); - cast = ConstraintCastNode::make_cast_for_type(x_ctrl, in, in_t, ConstraintCastNode::UnconditionalDependency); + cast = ConstraintCastNode::make_cast_for_type(x_ctrl, in, in_t, + ConstraintCastNode::UnconditionalDependency, nullptr); } if (cast != nullptr) { - register_new_node(cast, x_ctrl); + Node* prev = _igvn.hash_find_insert(cast); + if (prev != nullptr && get_ctrl(prev) == x_ctrl) { + cast->destruct(&_igvn); + cast = prev; + } else { + register_new_node(cast, x_ctrl); + } x->replace_edge(in, cast); - // Chain of AddP: - // 2- A CastPP of the base is only added now that both AddP nodes are sunk + // Chain of AddP nodes: + // 2- A CastPP of the base is only added now that all AddP nodes are sunk if (x->is_AddP() && k == AddPNode::Base) { - for (DUIterator_Fast imax, i = x->fast_outs(imax); i < imax; i++) { - Node* u = x->fast_out(i); - if (u->is_AddP() && u->in(AddPNode::Base) == n->in(AddPNode::Base)) { - _igvn.replace_input_of(u, AddPNode::Base, cast); - assert(u->find_out_with(Op_AddP) == nullptr, "more than 2 chained AddP nodes?"); - } - } + update_addp_chain_base(x, n->in(AddPNode::Base), cast); } break; } @@ -1722,6 +1724,22 @@ } } +void PhaseIdealLoop::update_addp_chain_base(Node* x, Node* old_base, Node* new_base) { + ResourceMark rm; + Node_List wq; + wq.push(x); + while (wq.size() != 0) { + Node* n = wq.pop(); + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* u = n->fast_out(i); + if (u->is_AddP() && u->in(AddPNode::Base) == old_base) { + _igvn.replace_input_of(u, AddPNode::Base, new_base); + wq.push(u); + } + } + } +} + // Compute the early control of a node by following its inputs until we reach // nodes that are pinned. Then compute the LCA of the control of all pinned nodes. Node* PhaseIdealLoop::compute_early_ctrl(Node* n, Node* n_ctrl) { @@ -2013,17 +2031,6 @@ return (CmpNode*)cmp; } -//------------------------------sink_use--------------------------------------- -// If 'use' was in the loop-exit block, it now needs to be sunk -// below the post-loop merge point. -void PhaseIdealLoop::sink_use( Node *use, Node *post_loop ) { - if (!use->is_CFG() && get_ctrl(use) == post_loop->in(2)) { - set_ctrl(use, post_loop); - for (DUIterator j = use->outs(); use->has_out(j); j++) - sink_use(use->out(j), post_loop); - } -} - void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new, IdealLoopTree* loop, IdealLoopTree* outer_loop, Node_List*& split_if_set, Node_List*& split_bool_set, @@ -2090,7 +2097,7 @@ while( use->in(idx) != old ) idx++; Node *prev = use->is_CFG() ? use : get_ctrl(use); assert(!loop->is_member(get_loop(prev)) && !outer_loop->is_member(get_loop(prev)), "" ); - Node *cfg = prev->_idx >= new_counter + Node* cfg = (prev->_idx >= new_counter && prev->is_Region()) ? prev->in(2) : idom(prev); if( use->is_Phi() ) // Phi use is in prior block @@ -2114,7 +2121,7 @@ while(!outer_loop->is_member(get_loop(cfg))) { prev = cfg; - cfg = cfg->_idx >= new_counter ? cfg->in(2) : idom(cfg); + cfg = (cfg->_idx >= new_counter && cfg->is_Region()) ? cfg->in(2) : idom(cfg); } // If the use occurs after merging several exits from the loop, then // old value must have dominated all those exits. Since the same old @@ -2172,10 +2179,6 @@ if( hit ) // Go ahead and re-hash for hits. _igvn.replace_node( use, hit ); } - - // If 'use' was in the loop-exit block, it now needs to be sunk - // below the post-loop merge point. - sink_use( use, prev ); } } } @@ -2542,8 +2545,6 @@ // We need a Region to merge the exit from the peeled body and the // exit from the old loop body. RegionNode *r = new RegionNode(3); - // Map the old use to the new merge point - old_new.map( use->_idx, r ); uint dd_r = MIN2(dom_depth(newuse), dom_depth(use)); assert(dd_r >= dom_depth(dom_lca(newuse, use)), "" ); @@ -2579,12 +2580,24 @@ l -= uses_found; // we deleted 1 or more copies of this edge } + assert(use->is_Proj(), "loop exit should be projection"); + // lazy_replace() below moves all nodes that are: + // - control dependent on the loop exit or + // - have control set to the loop exit + // below the post-loop merge point. lazy_replace() takes a dead control as first input. To make it + // possible to use it, the loop exit projection is cloned and becomes the new exit projection. The initial one + // becomes dead and is "replaced" by the region. + Node* use_clone = use->clone(); + register_control(use_clone, use_loop, idom(use), dom_depth(use)); // Now finish up 'r' r->set_req(1, newuse); - r->set_req(2, use); + r->set_req(2, use_clone); _igvn.register_new_node_with_optimizer(r); set_loop(r, use_loop); set_idom(r, (side_by_side_idom == nullptr) ? newuse->in(0) : side_by_side_idom, dd_r); + lazy_replace(use, r); + // Map the (cloned) old use to the new merge point + old_new.map(use_clone->_idx, r); } // End of if a loop-exit test } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/matcher.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/matcher.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/matcher.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/matcher.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -356,7 +356,9 @@ // Recursively match trees from old space into new space. // Correct leaves of new-space Nodes; they point to old-space. _visited.clear(); - C->set_cached_top_node(xform( C->top(), live_nodes )); + Node* const n = xform(C->top(), live_nodes); + if (C->failing()) return; + C->set_cached_top_node(n); if (!C->failing()) { Node* xroot = xform( C->root(), 1 ); if (xroot == nullptr) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/mulnode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/mulnode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/mulnode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/mulnode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -281,45 +281,86 @@ return res; // Return final result } -// Classes to perform mul_ring() for MulI/MulLNode. +// This template class performs type multiplication for MulI/MulLNode. NativeType is either jint or jlong. +// In this class, the inputs of the MulNodes are named left and right with types [left_lo,left_hi] and [right_lo,right_hi]. // -// This class checks if all cross products of the left and right input of a multiplication have the same "overflow value". -// Without overflow/underflow: -// Product is positive? High signed multiplication result: 0 -// Product is negative? High signed multiplication result: -1 -// -// We normalize these values (see normalize_overflow_value()) such that we get the same "overflow value" by adding 1 if -// the product is negative. This allows us to compare all the cross product "overflow values". If one is different, -// compared to the others, then we know that this multiplication has a different number of over- or underflows compared -// to the others. In this case, we need to use bottom type and cannot guarantee a better type. Otherwise, we can take -// the min und max of all computed cross products as type of this Mul node. -template -class IntegerMulRing { - using NativeType = std::conditional_t::value, jint, jlong>; +// In general, the multiplication of two x-bit values could produce a result that consumes up to 2x bits if there is +// enough space to hold them all. We can therefore distinguish the following two cases for the product: +// - no overflow (i.e. product fits into x bits) +// - overflow (i.e. product does not fit into x bits) +// +// When multiplying the two x-bit inputs 'left' and 'right' with their x-bit types [left_lo,left_hi] and [right_lo,right_hi] +// we need to find the minimum and maximum of all possible products to define a new type. To do that, we compute the +// cross product of [left_lo,left_hi] and [right_lo,right_hi] in 2x-bit space where no over- or underflow can happen. +// The cross product consists of the following four multiplications with 2x-bit results: +// (1) left_lo * right_lo +// (2) left_lo * right_hi +// (3) left_hi * right_lo +// (4) left_hi * right_hi +// +// Let's define the following two functions: +// - Lx(i): Returns the lower x bits of the 2x-bit number i. +// - Ux(i): Returns the upper x bits of the 2x-bit number i. +// +// Let's first assume all products are positive where only overflows are possible but no underflows. If there is no +// overflow for a product p, then the upper x bits of the 2x-bit result p are all zero: +// Ux(p) = 0 +// Lx(p) = p +// +// If none of the multiplications (1)-(4) overflow, we can truncate the upper x bits and use the following result type +// with x bits: +// [result_lo,result_hi] = [MIN(Lx(1),Lx(2),Lx(3),Lx(4)),MAX(Lx(1),Lx(2),Lx(3),Lx(4))] +// +// If any of these multiplications overflows, we could pessimistically take the bottom type for the x bit result +// (i.e. all values in the x-bit space could be possible): +// [result_lo,result_hi] = [NativeType_min,NativeType_max] +// +// However, in case of any overflow, we can do better by analyzing the upper x bits of all multiplications (1)-(4) with +// 2x-bit results. The upper x bits tell us something about how many times a multiplication has overflown the lower +// x bits. If the upper x bits of (1)-(4) are all equal, then we know that all of these multiplications overflowed +// the lower x bits the same number of times: +// Ux((1)) = Ux((2)) = Ux((3)) = Ux((4)) +// +// If all upper x bits are equal, we can conclude: +// Lx(MIN((1),(2),(3),(4))) = MIN(Lx(1),Lx(2),Lx(3),Lx(4))) +// Lx(MAX((1),(2),(3),(4))) = MAX(Lx(1),Lx(2),Lx(3),Lx(4))) +// +// Therefore, we can use the same precise x-bit result type as for the no-overflow case: +// [result_lo,result_hi] = [(MIN(Lx(1),Lx(2),Lx(3),Lx(4))),MAX(Lx(1),Lx(2),Lx(3),Lx(4)))] +// +// +// Now let's assume that (1)-(4) are signed multiplications where over- and underflow could occur: +// Negative numbers are all sign extend with ones. Therefore, if a negative product does not underflow, then the +// upper x bits of the 2x-bit result are all set to ones which is minus one in two's complement. If there is an underflow, +// the upper x bits are decremented by the number of times an underflow occurred. The smallest possible negative product +// is NativeType_min*NativeType_max, where the upper x bits are set to NativeType_min / 2 (b11...0). It is therefore +// impossible to underflow the upper x bits. Thus, when having all ones (i.e. minus one) in the upper x bits, we know +// that there is no underflow. +// +// To be able to compare the number of over-/underflows of positive and negative products, respectively, we normalize +// the upper x bits of negative 2x-bit products by adding one. This way a product has no over- or underflow if the +// normalized upper x bits are zero. Now we can use the same improved type as for strictly positive products because we +// can compare the upper x bits in a unified way with N() being the normalization function: +// N(Ux((1))) = N(Ux((2))) = N(Ux((3)) = N(Ux((4))) +template +class IntegerTypeMultiplication { NativeType _lo_left; NativeType _lo_right; NativeType _hi_left; NativeType _hi_right; - NativeType _lo_lo_product; - NativeType _lo_hi_product; - NativeType _hi_lo_product; - NativeType _hi_hi_product; short _widen_left; short _widen_right; static const Type* overflow_type(); - static NativeType multiply_high_signed_overflow_value(NativeType x, NativeType y); + static NativeType multiply_high(NativeType x, NativeType y); + const Type* create_type(NativeType lo, NativeType hi) const; - // Pre-compute cross products which are used at several places - void compute_cross_products() { - _lo_lo_product = java_multiply(_lo_left, _lo_right); - _lo_hi_product = java_multiply(_lo_left, _hi_right); - _hi_lo_product = java_multiply(_hi_left, _lo_right); - _hi_hi_product = java_multiply(_hi_left, _hi_right); + static NativeType multiply_high_signed_overflow_value(NativeType x, NativeType y) { + return normalize_overflow_value(x, y, multiply_high(x, y)); } - bool cross_products_not_same_overflow() const { + bool cross_product_not_same_overflow_value() const { const NativeType lo_lo_high_product = multiply_high_signed_overflow_value(_lo_left, _lo_right); const NativeType lo_hi_high_product = multiply_high_signed_overflow_value(_lo_left, _hi_right); const NativeType hi_lo_high_product = multiply_high_signed_overflow_value(_hi_left, _lo_right); @@ -329,66 +370,95 @@ hi_lo_high_product != hi_hi_high_product; } + bool does_product_overflow(NativeType x, NativeType y) const { + return multiply_high_signed_overflow_value(x, y) != 0; + } + static NativeType normalize_overflow_value(const NativeType x, const NativeType y, NativeType result) { return java_multiply(x, y) < 0 ? result + 1 : result; } public: - IntegerMulRing(const IntegerType* left, const IntegerType* right) : _lo_left(left->_lo), _lo_right(right->_lo), - _hi_left(left->_hi), _hi_right(right->_hi), _widen_left(left->_widen), _widen_right(right->_widen) { - compute_cross_products(); - } + template + IntegerTypeMultiplication(const IntegerType* left, const IntegerType* right) + : _lo_left(left->_lo), _lo_right(right->_lo), + _hi_left(left->_hi), _hi_right(right->_hi), + _widen_left(left->_widen), _widen_right(right->_widen) {} // Compute the product type by multiplying the two input type ranges. We take the minimum and maximum of all possible // values (requires 4 multiplications of all possible combinations of the two range boundary values). If any of these // multiplications overflows/underflows, we need to make sure that they all have the same number of overflows/underflows // If that is not the case, we return the bottom type to cover all values due to the inconsistent overflows/underflows). const Type* compute() const { - if (cross_products_not_same_overflow()) { + if (cross_product_not_same_overflow_value()) { return overflow_type(); } - const NativeType min = MIN4(_lo_lo_product, _lo_hi_product, _hi_lo_product, _hi_hi_product); - const NativeType max = MAX4(_lo_lo_product, _lo_hi_product, _hi_lo_product, _hi_hi_product); - return IntegerType::make(min, max, MAX2(_widen_left, _widen_right)); + + NativeType lo_lo_product = java_multiply(_lo_left, _lo_right); + NativeType lo_hi_product = java_multiply(_lo_left, _hi_right); + NativeType hi_lo_product = java_multiply(_hi_left, _lo_right); + NativeType hi_hi_product = java_multiply(_hi_left, _hi_right); + const NativeType min = MIN4(lo_lo_product, lo_hi_product, hi_lo_product, hi_hi_product); + const NativeType max = MAX4(lo_lo_product, lo_hi_product, hi_lo_product, hi_hi_product); + return create_type(min, max); } -}; + bool does_overflow() const { + return does_product_overflow(_lo_left, _lo_right) || + does_product_overflow(_lo_left, _hi_right) || + does_product_overflow(_hi_left, _lo_right) || + does_product_overflow(_hi_left, _hi_right); + } +}; template <> -const Type* IntegerMulRing::overflow_type() { +const Type* IntegerTypeMultiplication::overflow_type() { return TypeInt::INT; } template <> -jint IntegerMulRing::multiply_high_signed_overflow_value(const jint x, const jint y) { +jint IntegerTypeMultiplication::multiply_high(const jint x, const jint y) { const jlong x_64 = x; const jlong y_64 = y; const jlong product = x_64 * y_64; - const jint result = (jint)((uint64_t)product >> 32u); - return normalize_overflow_value(x, y, result); + return (jint)((uint64_t)product >> 32u); } template <> -const Type* IntegerMulRing::overflow_type() { +const Type* IntegerTypeMultiplication::create_type(jint lo, jint hi) const { + return TypeInt::make(lo, hi, MAX2(_widen_left, _widen_right)); +} + +template <> +const Type* IntegerTypeMultiplication::overflow_type() { return TypeLong::LONG; } template <> -jlong IntegerMulRing::multiply_high_signed_overflow_value(const jlong x, const jlong y) { - const jlong result = multiply_high_signed(x, y); - return normalize_overflow_value(x, y, result); +jlong IntegerTypeMultiplication::multiply_high(const jlong x, const jlong y) { + return multiply_high_signed(x, y); +} + +template <> +const Type* IntegerTypeMultiplication::create_type(jlong lo, jlong hi) const { + return TypeLong::make(lo, hi, MAX2(_widen_left, _widen_right)); } // Compute the product type of two integer ranges into this node. const Type* MulINode::mul_ring(const Type* type_left, const Type* type_right) const { - const IntegerMulRing integer_mul_ring(type_left->is_int(), type_right->is_int()); - return integer_mul_ring.compute(); + const IntegerTypeMultiplication integer_multiplication(type_left->is_int(), type_right->is_int()); + return integer_multiplication.compute(); +} + +bool MulINode::does_overflow(const TypeInt* type_left, const TypeInt* type_right) { + const IntegerTypeMultiplication integer_multiplication(type_left, type_right); + return integer_multiplication.does_overflow(); } // Compute the product type of two long ranges into this node. const Type* MulLNode::mul_ring(const Type* type_left, const Type* type_right) const { - const IntegerMulRing integer_mul_ring(type_left->is_long(), type_right->is_long()); - return integer_mul_ring.compute(); + const IntegerTypeMultiplication integer_multiplication(type_left->is_long(), type_right->is_long()); + return integer_multiplication.compute(); } //============================================================================= diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/mulnode.hpp openjdk-21-21.0.2+13/src/hotspot/share/opto/mulnode.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/mulnode.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/mulnode.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -95,6 +95,7 @@ virtual int Opcode() const; virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const Type *mul_ring( const Type *, const Type * ) const; + static bool does_overflow(const TypeInt* type_left, const TypeInt* type_right); const Type *mul_id() const { return TypeInt::ONE; } const Type *add_id() const { return TypeInt::ZERO; } int add_opcode() const { return Op_AddI; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/parse1.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/parse1.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/parse1.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/parse1.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1575,6 +1575,7 @@ #endif //ASSERT do_one_bytecode(); + if (failing()) return; assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth, "incorrect depth prediction: sp=%d, pre_bc_sp=%d, depth=%d", sp(), pre_bc_sp, depth); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/subnode.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/subnode.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/subnode.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/subnode.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -152,6 +152,16 @@ return !(is_cloop_increment(inc) || var->is_cloop_ind_var()); } +static bool is_cloop_condition(BoolNode* bol) { + for (DUIterator_Fast imax, i = bol->fast_outs(imax); i < imax; i++) { + Node* out = bol->fast_out(i); + if (out->is_CountedLoopEnd()) { + return true; + } + } + return false; +} + //------------------------------Ideal------------------------------------------ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ Node *in1 = in(1); @@ -1556,13 +1566,15 @@ // and "cmp (add X min_jint) c" into "cmpu X (c + min_jint)" if (cop == Op_CmpI && cmp1_op == Op_AddI && - phase->type(cmp1->in(2)) == TypeInt::MIN) { + phase->type(cmp1->in(2)) == TypeInt::MIN && + !is_cloop_condition(this)) { if (cmp2_op == Op_ConI) { Node* ncmp2 = phase->intcon(java_add(cmp2->get_int(), min_jint)); Node* ncmp = phase->transform(new CmpUNode(cmp1->in(1), ncmp2)); return new BoolNode(ncmp, _test._test); } else if (cmp2_op == Op_AddI && - phase->type(cmp2->in(2)) == TypeInt::MIN) { + phase->type(cmp2->in(2)) == TypeInt::MIN && + !is_cloop_condition(this)) { Node* ncmp = phase->transform(new CmpUNode(cmp1->in(1), cmp2->in(1))); return new BoolNode(ncmp, _test._test); } @@ -1572,13 +1584,15 @@ // and "cmp (add X min_jlong) c" into "cmpu X (c + min_jlong)" if (cop == Op_CmpL && cmp1_op == Op_AddL && - phase->type(cmp1->in(2)) == TypeLong::MIN) { + phase->type(cmp1->in(2)) == TypeLong::MIN && + !is_cloop_condition(this)) { if (cmp2_op == Op_ConL) { Node* ncmp2 = phase->longcon(java_add(cmp2->get_long(), min_jlong)); Node* ncmp = phase->transform(new CmpULNode(cmp1->in(1), ncmp2)); return new BoolNode(ncmp, _test._test); } else if (cmp2_op == Op_AddL && - phase->type(cmp2->in(2)) == TypeLong::MIN) { + phase->type(cmp2->in(2)) == TypeLong::MIN && + !is_cloop_condition(this)) { Node* ncmp = phase->transform(new CmpULNode(cmp1->in(1), cmp2->in(1))); return new BoolNode(ncmp, _test._test); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/superword.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/superword.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/superword.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/superword.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2701,18 +2701,18 @@ if (n->is_Load()) { Node* ctl = n->in(MemNode::Control); Node* mem = first->in(MemNode::Memory); + // Set the memory dependency of the LoadVector as early as possible. + // Walk up the memory chain, and ignore any StoreVector that provably + // does not have any memory dependency. SWPointer p1(n->as_Mem(), this, nullptr, false); - // Identify the memory dependency for the new loadVector node by - // walking up through memory chain. - // This is done to give flexibility to the new loadVector node so that - // it can move above independent storeVector nodes. while (mem->is_StoreVector()) { SWPointer p2(mem->as_Mem(), this, nullptr, false); - int cmp = p1.cmp(p2); - if (SWPointer::not_equal(cmp) || !SWPointer::comparable(cmp)) { + if (p1.not_equal(p2)) { + // Either Less or Greater -> provably no overlap between the two memory regions. mem = mem->in(MemNode::Memory); } else { - break; // dependent memory + // No proof that there is no overlap. Stop here. + break; } } Node* adr = first->in(MemNode::Address); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/opto/type.cpp openjdk-21-21.0.2+13/src/hotspot/share/opto/type.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/opto/type.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/opto/type.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -4749,7 +4749,7 @@ jint hi = size->_hi; jint lo = size->_lo; jint min_lo = 0; - jint max_hi = max_array_length(elem()->basic_type()); + jint max_hi = max_array_length(elem()->array_element_basic_type()); //if (index_not_size) --max_hi; // type of a valid array index, FTR bool chg = false; if (lo < min_lo) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgent.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgent.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgent.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgent.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -74,6 +74,10 @@ _options(copy_string(options)), _os_lib(nullptr), _os_lib_path(nullptr), +#ifdef AIX + _inode(0), + _device(0), +#endif _jplis(nullptr), _loaded(false), _absolute_path(is_absolute_path), @@ -118,6 +122,24 @@ return _os_lib_path; } +#ifdef AIX +void JvmtiAgent::set_inode(ino64_t inode) { + _inode = inode; +} + +void JvmtiAgent::set_device(dev64_t device) { + _device = device; +} + +ino64_t JvmtiAgent::inode() const { + return _inode; +} + +dev64_t JvmtiAgent::device() const { + return _device; +} +#endif + bool JvmtiAgent::is_loaded() const { return _loaded; } @@ -272,6 +294,20 @@ return os::find_builtin_agent(agent, &on_load_symbols[0], num_symbol_entries); } +#ifdef AIX +// save the inode and device of the library's file as a signature. This signature can be used +// in the same way as the library handle as a signature on other platforms. +static void save_library_signature(JvmtiAgent* agent, const char* name) { + struct stat64x libstat; + if (0 == os::Aix::stat64x_via_LIBPATH(name, &libstat)) { + agent->set_inode(libstat.st_ino); + agent->set_device(libstat.st_dev); + } else { + assert(false, "stat64x failed"); + } +} +#endif + // Load the library from the absolute path of the agent, if available. static void* load_agent_from_absolute_path(JvmtiAgent* agent, bool vm_exit_on_error) { DEBUG_ONLY(assert_preload(agent);) @@ -281,6 +317,7 @@ if (library == nullptr && vm_exit_on_error) { vm_exit(agent, " in absolute path, with error: ", nullptr); } + AIX_ONLY(if (library != nullptr) save_library_signature(agent, agent->name());) return library; } @@ -293,11 +330,13 @@ // Try to load the agent from the standard dll directory if (os::dll_locate_lib(&buffer[0], sizeof buffer, Arguments::get_dll_dir(), name)) { library = os::dll_load(&buffer[0], &ebuf[0], sizeof ebuf); + AIX_ONLY(if (library != nullptr) save_library_signature(agent, &buffer[0]);) } if (library == nullptr && os::dll_build_name(&buffer[0], sizeof buffer, name)) { // Try the library path directory. library = os::dll_load(&buffer[0], &ebuf[0], sizeof ebuf); if (library != nullptr) { + AIX_ONLY(save_library_signature(agent, &buffer[0]);) return library; } if (vm_exit_on_error) { @@ -515,7 +554,11 @@ agent->set_os_lib_path(&buffer[0]); agent->set_os_lib(library); agent->set_loaded(); + #ifdef AIX + previously_loaded = JvmtiAgentList::is_dynamic_lib_loaded(agent->device(), agent->inode()); + #else previously_loaded = JvmtiAgentList::is_dynamic_lib_loaded(library); + #endif } // Print warning if agent was not previously loaded and EnableDynamicAgentLoading not enabled on the command line. diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgent.hpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgent.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgent.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgent.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -43,6 +43,10 @@ const char* _options; void* _os_lib; const char* _os_lib_path; +#ifdef AIX + ino64_t _inode; + dev64_t _device; +#endif const void* _jplis; bool _loaded; bool _absolute_path; @@ -80,6 +84,12 @@ void initialization_end(); const Ticks& initialization_time() const; const Tickspan& initialization_duration() const; +#ifdef AIX + void set_inode(ino64_t inode); + void set_device(dev64_t device); + unsigned long inode() const; + unsigned long device() const; +#endif bool load(outputStream* st = nullptr); void unload(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgentList.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgentList.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgentList.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgentList.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -243,6 +243,19 @@ } return false; } +#ifdef AIX +bool JvmtiAgentList::is_dynamic_lib_loaded(dev64_t device, ino64_t inode) { + JvmtiAgentList::Iterator it = JvmtiAgentList::agents(); + while (it.has_next()) { + JvmtiAgent* const agent = it.next(); + if (!agent->is_static_lib() && device != 0 && inode != 0 && + agent->device() == device && agent->inode() == inode) { + return true; + } + } + return false; +} +#endif static bool match(JvmtiEnv* env, const JvmtiAgent* agent, const void* os_module_address) { assert(env != nullptr, "invariant"); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgentList.hpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgentList.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiAgentList.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiAgentList.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -78,6 +78,9 @@ static bool is_static_lib_loaded(const char* name); static bool is_dynamic_lib_loaded(void* os_lib); +#ifdef AIX + static bool is_dynamic_lib_loaded(dev64_t device, ino64_t inode); +#endif static JvmtiAgent* lookup(JvmtiEnv* env, void* f_ptr); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEnv.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEnv.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEnv.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEnv.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1009,7 +1009,7 @@ jvmtiError JvmtiEnv::SuspendAllVirtualThreads(jint except_count, const jthread* except_list) { - if (!JvmtiExport::can_support_virtual_threads()) { + if (get_capabilities()->can_support_virtual_threads == 0) { return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } JavaThread* current = JavaThread::current(); @@ -1127,7 +1127,7 @@ jvmtiError JvmtiEnv::ResumeAllVirtualThreads(jint except_count, const jthread* except_list) { - if (!JvmtiExport::can_support_virtual_threads()) { + if (get_capabilities()->can_support_virtual_threads == 0) { return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } jvmtiError err = JvmtiEnvBase::check_thread_list(except_count, except_list); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEnvBase.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEnvBase.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEnvBase.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEnvBase.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -213,7 +213,8 @@ _is_retransformable = true; // all callbacks initially null - memset(&_event_callbacks,0,sizeof(jvmtiEventCallbacks)); + memset(&_event_callbacks, 0, sizeof(jvmtiEventCallbacks)); + memset(&_ext_event_callbacks, 0, sizeof(jvmtiExtEventCallbacks)); // all capabilities initially off memset(&_current_capabilities, 0, sizeof(_current_capabilities)); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEventController.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEventController.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEventController.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEventController.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -309,6 +309,8 @@ static void clear_to_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop); static void change_field_watch(jvmtiEvent event_type, bool added); + static bool is_any_thread_filtered_event_enabled_globally(); + static void recompute_thread_filtered(JvmtiThreadState *state); static void thread_started(JavaThread *thread); static void thread_ended(JavaThread *thread); @@ -729,6 +731,20 @@ EC_TRACE(("[-] # recompute enabled - after " JULONG_FORMAT_X, any_env_thread_enabled)); } +bool +JvmtiEventControllerPrivate::is_any_thread_filtered_event_enabled_globally() { + julong global_thread_events = JvmtiEventController::_universal_global_event_enabled.get_bits() & THREAD_FILTERED_EVENT_BITS; + return global_thread_events != 0L; +} + +void +JvmtiEventControllerPrivate::recompute_thread_filtered(JvmtiThreadState *state) { + assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check"); + + if (is_any_thread_filtered_event_enabled_globally()) { + JvmtiEventControllerPrivate::recompute_thread_enabled(state); + } +} void JvmtiEventControllerPrivate::thread_started(JavaThread *thread) { @@ -738,17 +754,11 @@ EC_TRACE(("[%s] # thread started", JvmtiTrace::safe_get_thread_name(thread))); // if we have any thread filtered events globally enabled, create/update the thread state - if ((JvmtiEventController::_universal_global_event_enabled.get_bits() & THREAD_FILTERED_EVENT_BITS) != 0) { - MutexLocker mu(JvmtiThreadState_lock); - // create the thread state if missing - JvmtiThreadState *state = JvmtiThreadState::state_for_while_locked(thread); - if (state != nullptr) { // skip threads with no JVMTI thread state - recompute_thread_enabled(state); - } + if (is_any_thread_filtered_event_enabled_globally()) { // intentionally racy + JvmtiThreadState::state_for(thread); } } - void JvmtiEventControllerPrivate::thread_ended(JavaThread *thread) { // Removes the JvmtiThreadState associated with the specified thread. @@ -1115,6 +1125,11 @@ } void +JvmtiEventController::recompute_thread_filtered(JvmtiThreadState *state) { + JvmtiEventControllerPrivate::recompute_thread_filtered(state); +} + +void JvmtiEventController::thread_started(JavaThread *thread) { // operates only on the current thread // JvmtiThreadState_lock grabbed only if needed. diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEventController.hpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEventController.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiEventController.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiEventController.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -234,6 +234,7 @@ static void change_field_watch(jvmtiEvent event_type, bool added); + static void recompute_thread_filtered(JvmtiThreadState *state); static void thread_started(JavaThread *thread); static void thread_ended(JavaThread *thread); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiExport.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiExport.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiExport.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiExport.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -417,6 +417,15 @@ } } +JvmtiThreadState* +JvmtiExport::get_jvmti_thread_state(JavaThread *thread) { + assert(thread == JavaThread::current(), "must be current thread"); + if (thread->is_vthread_mounted() && thread->jvmti_thread_state() == nullptr) { + JvmtiEventController::thread_started(thread); + } + return thread->jvmti_thread_state(); +} + void JvmtiExport::add_default_read_edges(Handle h_module, TRAPS) { if (!Universe::is_module_initialized()) { @@ -920,7 +929,7 @@ _has_been_modified = false; assert(!_thread->is_in_any_VTMS_transition(), "CFLH events are not allowed in any VTMS transition"); - _state = _thread->jvmti_thread_state(); + _state = JvmtiExport::get_jvmti_thread_state(_thread); if (_state != nullptr) { _class_being_redefined = _state->get_class_being_redefined(); _load_kind = _state->get_class_load_kind(); @@ -1209,7 +1218,7 @@ HandleMark hm(thread); methodHandle mh(thread, method); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1307,7 +1316,7 @@ methodHandle mh(thread, method); // update information about current location and post a step event - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1326,7 +1335,7 @@ void JvmtiExport::expose_single_stepping(JavaThread *thread) { - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state != nullptr) { state->clear_hide_single_stepping(); } @@ -1334,7 +1343,7 @@ bool JvmtiExport::hide_single_stepping(JavaThread *thread) { - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state != nullptr && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { state->set_hide_single_stepping(); return true; @@ -1349,7 +1358,7 @@ } HandleMark hm(thread); - JvmtiThreadState* state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1387,7 +1396,7 @@ } HandleMark hm(thread); - JvmtiThreadState* state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1516,7 +1525,7 @@ EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_END, ("[%s] Trg Thread End event triggered", JvmtiTrace::safe_get_thread_name(thread))); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1564,7 +1573,7 @@ EVT_TRIG_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_START, ("[%p] Trg Virtual Thread Start event triggered", vthread)); JavaThread *cur_thread = JavaThread::current(); - JvmtiThreadState *state = cur_thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(cur_thread); if (state == nullptr) { return; } @@ -1598,7 +1607,7 @@ EVT_TRIG_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_END, ("[%p] Trg Virtual Thread End event triggered", vthread)); JavaThread *cur_thread = JavaThread::current(); - JvmtiThreadState *state = cur_thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(cur_thread); if (state == nullptr) { return; } @@ -1633,7 +1642,7 @@ HandleMark hm(thread); EVT_TRIG_TRACE(EXT_EVENT_VIRTUAL_THREAD_MOUNT, ("[%p] Trg Virtual Thread Mount event triggered", vthread)); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1668,7 +1677,7 @@ HandleMark hm(thread); EVT_TRIG_TRACE(EXT_EVENT_VIRTUAL_THREAD_UNMOUNT, ("[%p] Trg Virtual Thread Unmount event triggered", vthread)); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1701,7 +1710,7 @@ } assert(thread == JavaThread::current(), "must be"); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1795,7 +1804,7 @@ HandleMark hm(thread); methodHandle mh(thread, method); - JvmtiThreadState* state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr || !state->is_interp_only_mode()) { // for any thread that actually wants method entry, interp_only_mode is set return; @@ -1835,7 +1844,7 @@ HandleMark hm(thread); methodHandle mh(thread, method); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr || !state->is_interp_only_mode()) { // for any thread that actually wants method exit, interp_only_mode is set @@ -1956,7 +1965,7 @@ HandleMark hm(thread); methodHandle mh(thread, method); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -1998,7 +2007,7 @@ // ensure the stack is sufficiently processed. KeepStackGCProcessedMark ksgcpm(thread); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2086,7 +2095,7 @@ methodHandle mh(thread, method); Handle exception_handle(thread, exception); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2202,7 +2211,7 @@ HandleMark hm(thread); methodHandle mh(thread, method); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2358,7 +2367,7 @@ HandleMark hm(thread); methodHandle mh(thread, method); - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2600,7 +2609,7 @@ // jvmti thread state. // The collector and/or state might be null if JvmtiDynamicCodeEventCollector // has been initialized while JVMTI_EVENT_DYNAMIC_CODE_GENERATED was disabled. - JvmtiThreadState* state = thread->jvmti_thread_state(); + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state != nullptr) { JvmtiDynamicCodeEventCollector *collector = state->get_dynamic_code_event_collector(); if (collector != nullptr) { @@ -2719,7 +2728,10 @@ void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) { oop object = obj_mntr->object(); - JvmtiThreadState *state = thread->jvmti_thread_state(); + HandleMark hm(thread); + Handle h(thread, object); + + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2727,9 +2739,6 @@ return; // no events should be posted if thread is in any VTMS transition } - HandleMark hm(thread); - Handle h(thread, object); - EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, ("[%s] monitor contended enter event triggered", JvmtiTrace::safe_get_thread_name(thread))); @@ -2752,7 +2761,10 @@ void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) { oop object = obj_mntr->object(); - JvmtiThreadState *state = thread->jvmti_thread_state(); + HandleMark hm(thread); + Handle h(thread, object); + + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2760,9 +2772,6 @@ return; // no events should be posted if thread is in any VTMS transition } - HandleMark hm(thread); - Handle h(thread, object); - EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, ("[%s] monitor contended entered event triggered", JvmtiTrace::safe_get_thread_name(thread))); @@ -2786,7 +2795,10 @@ void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object, jlong timeout) { - JvmtiThreadState *state = thread->jvmti_thread_state(); + HandleMark hm(thread); + Handle h(thread, object); + + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2794,9 +2806,6 @@ return; // no events should be posted if thread is in any VTMS transition } - HandleMark hm(thread); - Handle h(thread, object); - EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT, ("[%s] monitor wait event triggered", JvmtiTrace::safe_get_thread_name(thread))); @@ -2820,7 +2829,10 @@ void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) { oop object = obj_mntr->object(); - JvmtiThreadState *state = thread->jvmti_thread_state(); + HandleMark hm(thread); + Handle h(thread, object); + + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2828,9 +2840,6 @@ return; // no events should be posted if thread is in any VTMS transition } - HandleMark hm(thread); - Handle h(thread, object); - EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED, ("[%s] monitor waited event triggered", JvmtiTrace::safe_get_thread_name(thread))); @@ -2883,7 +2892,10 @@ } void JvmtiExport::post_sampled_object_alloc(JavaThread *thread, oop object) { - JvmtiThreadState *state = thread->jvmti_thread_state(); + HandleMark hm(thread); + Handle h(thread, object); + + JvmtiThreadState *state = get_jvmti_thread_state(thread); if (state == nullptr) { return; } @@ -2893,8 +2905,6 @@ if (thread->is_in_any_VTMS_transition()) { return; // no events should be posted if thread is in any VTMS transition } - HandleMark hm(thread); - Handle h(thread, object); EVT_TRIG_TRACE(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC, ("[%s] Trg sampled object alloc triggered", diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiExport.hpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiExport.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiExport.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiExport.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -298,6 +298,11 @@ static void decode_version_values(jint version, int * major, int * minor, int * micro) NOT_JVMTI_RETURN; + // If the jvmti_thread_state is absent and any thread filtered event + // is enabled globally then it is created. + // Otherwise, the thread->jvmti_thread_state() is returned. + static JvmtiThreadState* get_jvmti_thread_state(JavaThread *thread); + // single stepping management methods static void at_single_stepping_point(JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN; static void expose_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiManageCapabilities.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiManageCapabilities.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiManageCapabilities.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiManageCapabilities.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "jvmtifiles/jvmtiEnv.hpp" #include "logging/log.hpp" +#include "runtime/mutexLocker.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiManageCapabilities.hpp" @@ -55,7 +56,12 @@ // all capabilities ever acquired jvmtiCapabilities JvmtiManageCapabilities::acquired_capabilities; +int JvmtiManageCapabilities::_can_support_virtual_threads_count = 0; + +Mutex* JvmtiManageCapabilities::_capabilities_lock = nullptr; + void JvmtiManageCapabilities::initialize() { + _capabilities_lock = new Mutex(Mutex::nosafepoint, "Capabilities_lock"); always_capabilities = init_always_capabilities(); onload_capabilities = init_onload_capabilities(); always_solo_capabilities = init_always_solo_capabilities(); @@ -211,8 +217,14 @@ } } +Mutex* JvmtiManageCapabilities::lock() { + if (Thread::current_or_null() == nullptr) { + return nullptr; // Detached thread, can be a call from Agent_OnLoad. + } + return _capabilities_lock; +} -void JvmtiManageCapabilities::get_potential_capabilities(const jvmtiCapabilities *current, +void JvmtiManageCapabilities::get_potential_capabilities_nolock(const jvmtiCapabilities *current, const jvmtiCapabilities *prohibited, jvmtiCapabilities *result) { // exclude prohibited capabilities, must be before adding current @@ -231,13 +243,22 @@ } } +void JvmtiManageCapabilities::get_potential_capabilities(const jvmtiCapabilities* current, + const jvmtiCapabilities* prohibited, + jvmtiCapabilities* result) { + MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag); + get_potential_capabilities_nolock(current, prohibited, result); +} + jvmtiError JvmtiManageCapabilities::add_capabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *prohibited, const jvmtiCapabilities *desired, jvmtiCapabilities *result) { + MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag); + // check that the capabilities being added are potential capabilities jvmtiCapabilities temp; - get_potential_capabilities(current, prohibited, &temp); + get_potential_capabilities_nolock(current, prohibited, &temp); if (has_some(exclude(desired, &temp, &temp))) { return JVMTI_ERROR_NOT_AVAILABLE; } @@ -259,6 +280,10 @@ exclude(&always_solo_remaining_capabilities, desired, &always_solo_remaining_capabilities); exclude(&onload_solo_remaining_capabilities, desired, &onload_solo_remaining_capabilities); + if (desired->can_support_virtual_threads != 0 && current->can_support_virtual_threads == 0) { + _can_support_virtual_threads_count++; + } + // return the result either(current, desired, result); @@ -271,6 +296,8 @@ void JvmtiManageCapabilities::relinquish_capabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *unwanted, jvmtiCapabilities *result) { + MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag); + jvmtiCapabilities to_trash; jvmtiCapabilities temp; @@ -283,6 +310,12 @@ either(&onload_solo_remaining_capabilities, both(&onload_solo_capabilities, &to_trash, &temp), &onload_solo_remaining_capabilities); + if (to_trash.can_support_virtual_threads != 0) { + assert(current->can_support_virtual_threads != 0, "sanity check"); + assert(_can_support_virtual_threads_count > 0, "sanity check"); + _can_support_virtual_threads_count--; + } + update(); // return the result @@ -366,7 +399,7 @@ JvmtiExport::set_can_post_frame_pop(avail.can_generate_frame_pop_events); JvmtiExport::set_can_pop_frame(avail.can_pop_frame); JvmtiExport::set_can_force_early_return(avail.can_force_early_return); - JvmtiExport::set_can_support_virtual_threads(avail.can_support_virtual_threads); + JvmtiExport::set_can_support_virtual_threads(_can_support_virtual_threads_count != 0); JvmtiExport::set_should_clean_up_heap_objects(avail.can_generate_breakpoint_events); JvmtiExport::set_can_get_owned_monitor_info(avail.can_get_owned_monitor_info || avail.can_get_owned_monitor_stack_depth_info); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiManageCapabilities.hpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiManageCapabilities.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiManageCapabilities.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiManageCapabilities.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -48,6 +48,12 @@ // all capabilities ever acquired static jvmtiCapabilities acquired_capabilities; + // counter for the agents possess can_support_virtual_threads capability + static int _can_support_virtual_threads_count; + + // lock to access the class data + static Mutex* _capabilities_lock; + // basic intenal operations static jvmtiCapabilities *either(const jvmtiCapabilities *a, const jvmtiCapabilities *b, jvmtiCapabilities *result); static jvmtiCapabilities *both(const jvmtiCapabilities *a, const jvmtiCapabilities *b, jvmtiCapabilities *result); @@ -61,6 +67,14 @@ static jvmtiCapabilities init_always_solo_capabilities(); static jvmtiCapabilities init_onload_solo_capabilities(); + // returns nullptr in onload phase + static Mutex* lock(); + + // get_potential_capabilities without lock + static void get_potential_capabilities_nolock(const jvmtiCapabilities* current, + const jvmtiCapabilities* prohibited, + jvmtiCapabilities* result); + public: static void initialize(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiTagMap.cpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiTagMap.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiTagMap.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiTagMap.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -2320,7 +2320,10 @@ // Follow oops from compiled nmethod. if (jvf->cb() != nullptr && jvf->cb()->is_nmethod()) { _blk->set_context(_thread_tag, _tid, _depth, method); - jvf->cb()->as_nmethod()->oops_do(_blk); + // Need to apply load barriers for unmounted vthreads. + nmethod* nm = jvf->cb()->as_nmethod(); + nm->run_nmethod_entry_barrier(); + nm->oops_do(_blk); if (_blk->stopped()) { return false; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiThreadState.hpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiThreadState.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiThreadState.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiThreadState.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -465,9 +465,12 @@ // already holding JvmtiThreadState_lock - retrieve or create JvmtiThreadState // Can return null if JavaThread is exiting. + // Callers are responsible to call recompute_thread_filtered() to update event bits + // if thread-filtered events are enabled globally. static JvmtiThreadState *state_for_while_locked(JavaThread *thread, oop thread_oop = nullptr); // retrieve or create JvmtiThreadState // Can return null if JavaThread is exiting. + // Calls recompute_thread_filtered() to update event bits if thread-filtered events are enabled globally. static JvmtiThreadState *state_for(JavaThread *thread, Handle thread_handle = Handle()); // JVMTI ForceEarlyReturn support diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiThreadState.inline.hpp openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiThreadState.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/prims/jvmtiThreadState.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/prims/jvmtiThreadState.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -109,6 +109,7 @@ MutexLocker mu(JvmtiThreadState_lock); // check again with the lock held state = state_for_while_locked(thread, thread_handle()); + JvmtiEventController::recompute_thread_filtered(state); } else { // Check possible safepoint even if state is non-null. // (Note: the thread argument isn't the current thread) diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/arguments.cpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/arguments.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/arguments.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/arguments.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1904,23 +1904,13 @@ } #endif - -#if !defined(X86) && !defined(AARCH64) && !defined(RISCV64) && !defined(ARM) && !defined(PPC64) +#if !defined(X86) && !defined(AARCH64) && !defined(RISCV64) && !defined(ARM) && !defined(PPC64) && !defined(S390) if (LockingMode == LM_LIGHTWEIGHT) { FLAG_SET_CMDLINE(LockingMode, LM_LEGACY); warning("New lightweight locking not supported on this platform"); } #endif - if (UseHeavyMonitors) { - if (FLAG_IS_CMDLINE(LockingMode) && LockingMode != LM_MONITOR) { - jio_fprintf(defaultStream::error_stream(), - "Conflicting -XX:+UseHeavyMonitors and -XX:LockingMode=%d flags", LockingMode); - return false; - } - FLAG_SET_CMDLINE(LockingMode, LM_MONITOR); - } - #if !defined(X86) && !defined(AARCH64) && !defined(PPC64) && !defined(RISCV64) && !defined(S390) if (LockingMode == LM_MONITOR) { jio_fprintf(defaultStream::error_stream(), diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/continuationWrapper.cpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/continuationWrapper.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/continuationWrapper.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/continuationWrapper.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -38,16 +38,12 @@ #include "runtime/stackChunkFrameStream.inline.hpp" ContinuationWrapper::ContinuationWrapper(const RegisterMap* map) - : _thread(map->thread()), - _entry(Continuation::get_continuation_entry_for_continuation(_thread, map->stack_chunk()->cont())), - _continuation(map->stack_chunk()->cont()) - { - assert(oopDesc::is_oop(_continuation),"Invalid cont: " INTPTR_FORMAT, p2i((void*)_continuation)); + : ContinuationWrapper(map->thread(), + Continuation::get_continuation_entry_for_continuation(map->thread(), map->stack_chunk()->cont()), + map->stack_chunk()->cont()) { assert(_entry == nullptr || _continuation == _entry->cont_oop(map->thread()), "cont: " INTPTR_FORMAT " entry: " INTPTR_FORMAT " entry_sp: " INTPTR_FORMAT, p2i( (oopDesc*)_continuation), p2i((oopDesc*)_entry->cont_oop(map->thread())), p2i(entrySP())); - disallow_safepoint(); - read(); } const frame ContinuationWrapper::last_frame() { @@ -96,4 +92,3 @@ return true; } #endif // ASSERT - diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/continuationWrapper.inline.hpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/continuationWrapper.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/continuationWrapper.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/continuationWrapper.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -49,6 +49,7 @@ // These oops are managed by SafepointOp oop _continuation; // jdk.internal.vm.Continuation instance stackChunkOop _tail; + bool _done; ContinuationWrapper(const ContinuationWrapper& cont); // no copy constructor @@ -58,6 +59,7 @@ void disallow_safepoint() { #ifdef ASSERT + assert(!_done, ""); assert(_continuation != nullptr, ""); _current_thread = Thread::current(); if (_current_thread->is_Java_thread()) { @@ -69,16 +71,19 @@ void allow_safepoint() { #ifdef ASSERT // we could have already allowed safepoints in done - if (_continuation != nullptr && _current_thread->is_Java_thread()) { + if (!_done && _current_thread->is_Java_thread()) { JavaThread::cast(_current_thread)->dec_no_safepoint_count(); } #endif } + ContinuationWrapper(JavaThread* thread, ContinuationEntry* entry, oop continuation); + public: void done() { allow_safepoint(); // must be done first - _continuation = nullptr; + _done = true; + *reinterpret_cast(&_continuation) = badHeapOopVal; *reinterpret_cast(&_tail) = badHeapOopVal; } @@ -140,23 +145,19 @@ #endif }; -inline ContinuationWrapper::ContinuationWrapper(JavaThread* thread, oop continuation) - : _thread(thread), _entry(thread->last_continuation()), _continuation(continuation) - { +inline ContinuationWrapper::ContinuationWrapper(JavaThread* thread, ContinuationEntry* entry, oop continuation) + : _thread(thread), _entry(entry), _continuation(continuation), _done(false) { assert(oopDesc::is_oop(_continuation), "Invalid continuation object: " INTPTR_FORMAT, p2i((void*)_continuation)); disallow_safepoint(); read(); } +inline ContinuationWrapper::ContinuationWrapper(JavaThread* thread, oop continuation) + : ContinuationWrapper(thread, thread->last_continuation(), continuation) {} + inline ContinuationWrapper::ContinuationWrapper(oop continuation) - : _thread(nullptr), _entry(nullptr), _continuation(continuation) - { - assert(oopDesc::is_oop(_continuation), - "Invalid continuation object: " INTPTR_FORMAT, p2i((void*)_continuation)); - disallow_safepoint(); - read(); -} + : ContinuationWrapper(nullptr, nullptr, continuation) {} inline bool ContinuationWrapper::is_preempted() { return jdk_internal_vm_Continuation::is_preempted(_continuation); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/deoptimization.cpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/deoptimization.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/deoptimization.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/deoptimization.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -82,6 +82,7 @@ #include "runtime/stackValue.hpp" #include "runtime/stackWatermarkSet.hpp" #include "runtime/stubRoutines.hpp" +#include "runtime/synchronizer.hpp" #include "runtime/threadSMR.hpp" #include "runtime/threadWXSetters.inline.hpp" #include "runtime/vframe.hpp" @@ -1648,9 +1649,19 @@ } } } - BasicLock* lock = mon_info->lock(); - ObjectSynchronizer::enter(obj, lock, deoptee_thread); - assert(mon_info->owner()->is_locked(), "object must be locked now"); + if (LockingMode == LM_LIGHTWEIGHT && exec_mode == Unpack_none) { + // We have lost information about the correct state of the lock stack. + // Inflate the locks instead. Enter then inflate to avoid races with + // deflation. + ObjectSynchronizer::enter(obj, nullptr, deoptee_thread); + assert(mon_info->owner()->is_locked(), "object must be locked now"); + ObjectMonitor* mon = ObjectSynchronizer::inflate(deoptee_thread, obj(), ObjectSynchronizer::inflate_cause_vm_internal); + assert(mon->owner() == deoptee_thread, "must be"); + } else { + BasicLock* lock = mon_info->lock(); + ObjectSynchronizer::enter(obj, lock, deoptee_thread); + assert(mon_info->owner()->is_locked(), "object must be locked now"); + } } } } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/frame.hpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/frame.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/frame.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/frame.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -372,6 +372,7 @@ BasicObjectLock* next_monitor_in_interpreter_frame(BasicObjectLock* current) const; BasicObjectLock* previous_monitor_in_interpreter_frame(BasicObjectLock* current) const; static int interpreter_frame_monitor_size(); + static int interpreter_frame_monitor_size_in_bytes(); void interpreter_frame_verify_monitor(BasicObjectLock* value) const; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/frame.inline.hpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/frame.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/frame.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/frame.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -104,4 +104,9 @@ return _cb; } +inline int frame::interpreter_frame_monitor_size_in_bytes() { + // Number of bytes for a monitor. + return frame::interpreter_frame_monitor_size() * wordSize; +} + #endif // SHARE_RUNTIME_FRAME_INLINE_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/globals.hpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/globals.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/globals.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/globals.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -1050,13 +1050,9 @@ product(bool, ErrorFileToStdout, false, \ "If true, error data is printed to stdout instead of a file") \ \ - develop(bool, UseHeavyMonitors, false, \ - "(Deprecated) Use heavyweight instead of lightweight Java " \ - "monitors") \ - \ develop(bool, VerifyHeavyMonitors, false, \ "Checks that no stack locking happens when using " \ - "+UseHeavyMonitors") \ + "-XX:LockingMode=0 (LM_MONITOR)") \ \ product(bool, PrintStringTableStatistics, false, \ "print statistics about the StringTable and SymbolTable") \ diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/lockStack.cpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/lockStack.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/lockStack.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/lockStack.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -77,3 +77,15 @@ } } #endif + +void LockStack::print_on(outputStream* st) { + for (int i = to_index(_top); (--i) >= 0;) { + st->print("LockStack[%d]: ", i); + oop o = _base[i]; + if (oopDesc::is_oop(o)) { + o->print_on(st); + } else { + st->print_cr("not an oop: " PTR_FORMAT, p2i(o)); + } + } +} diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/lockStack.hpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/lockStack.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/lockStack.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/lockStack.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -30,8 +30,9 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/sizes.hpp" -class Thread; +class JavaThread; class OopClosure; +class outputStream; class LockStack { friend class VMStructs; @@ -91,6 +92,8 @@ // GC support inline void oops_do(OopClosure* cl); + // Printing + void print_on(outputStream* st); }; #endif // SHARE_RUNTIME_LOCKSTACK_HPP diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/lockStack.inline.hpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/lockStack.inline.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/lockStack.inline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/lockStack.inline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -47,10 +47,14 @@ } inline bool LockStack::is_owning_thread() const { - JavaThread* thread = JavaThread::current(); - bool is_owning = &thread->lock_stack() == this; - assert(is_owning == (get_thread() == thread), "is_owning sanity"); - return is_owning; + Thread* current = Thread::current(); + if (current->is_Java_thread()) { + JavaThread* thread = JavaThread::cast(current); + bool is_owning = &thread->lock_stack() == this; + assert(is_owning == (get_thread() == thread), "is_owning sanity"); + return is_owning; + } + return false; } inline void LockStack::push(oop o) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/os.cpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/os.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/os.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/os.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1391,7 +1391,7 @@ if (res == OS_ERR) { return false; } - buf = (void *)((char *)buf + nBytes); + buf = (void *)((char *)buf + res); nBytes -= res; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/runtime/synchronizer.cpp openjdk-21-21.0.2+13/src/hotspot/share/runtime/synchronizer.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/runtime/synchronizer.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/runtime/synchronizer.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/vmSymbols.hpp" -#include "gc/shared/suspendibleThreadSet.hpp" +#include "gc/shared/collectedHeap.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" @@ -1641,8 +1641,8 @@ bool evaluate_at_safepoint() const override { return false; } VMOp_Type type() const override { return VMOp_RendezvousGCThreads; } void doit() override { - SuspendibleThreadSet::synchronize(); - SuspendibleThreadSet::desynchronize(); + Universe::heap()->safepoint_synchronize_begin(); + Universe::heap()->safepoint_synchronize_end(); }; }; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/heapDumper.cpp openjdk-21-21.0.2+13/src/hotspot/share/services/heapDumper.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/heapDumper.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/heapDumper.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -37,6 +37,7 @@ #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" +#include "oops/fieldStreams.inline.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" @@ -48,7 +49,6 @@ #include "runtime/javaThread.inline.hpp" #include "runtime/jniHandles.hpp" #include "runtime/os.hpp" -#include "runtime/reflectionUtils.hpp" #include "runtime/threads.hpp" #include "runtime/threadSMR.hpp" #include "runtime/vframe.hpp" @@ -1096,7 +1096,7 @@ InstanceKlass* ik = InstanceKlass::cast(k); u4 size = 0; - for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) { + for (HierarchicalFieldStream fld(ik); !fld.done(); fld.next()) { if (!fld.access_flags().is_static()) { size += sig2size(fld.signature()); } @@ -1108,7 +1108,7 @@ field_count = 0; u4 size = 0; - for (FieldStream fldc(ik, true, true); !fldc.eos(); fldc.next()) { + for (JavaFieldStream fldc(ik); !fldc.done(); fldc.next()) { if (fldc.access_flags().is_static()) { field_count++; size += sig2size(fldc.signature()); @@ -1142,7 +1142,7 @@ InstanceKlass* ik = InstanceKlass::cast(k); // dump the field descriptors and raw values - for (FieldStream fld(ik, true, true); !fld.eos(); fld.next()) { + for (JavaFieldStream fld(ik); !fld.done(); fld.next()) { if (fld.access_flags().is_static()) { Symbol* sig = fld.signature(); @@ -1176,7 +1176,7 @@ void DumperSupport::dump_instance_fields(AbstractDumpWriter* writer, oop o) { InstanceKlass* ik = InstanceKlass::cast(o->klass()); - for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) { + for (HierarchicalFieldStream fld(ik); !fld.done(); fld.next()) { if (!fld.access_flags().is_static()) { Symbol* sig = fld.signature(); dump_field_value(writer, sig->char_at(0), o, fld.offset()); @@ -1188,7 +1188,7 @@ u2 DumperSupport::get_instance_fields_count(InstanceKlass* ik) { u2 field_count = 0; - for (FieldStream fldc(ik, true, true); !fldc.eos(); fldc.next()) { + for (JavaFieldStream fldc(ik); !fldc.done(); fldc.next()) { if (!fldc.access_flags().is_static()) field_count++; } @@ -1200,7 +1200,7 @@ InstanceKlass* ik = InstanceKlass::cast(k); // dump the field descriptors - for (FieldStream fld(ik, true, true); !fld.eos(); fld.next()) { + for (JavaFieldStream fld(ik); !fld.done(); fld.next()) { if (!fld.access_flags().is_static()) { Symbol* sig = fld.signature(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/mallocTracker.cpp openjdk-21-21.0.2+13/src/hotspot/share/services/mallocTracker.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/mallocTracker.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/mallocTracker.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -45,7 +45,6 @@ size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)]; -#ifdef ASSERT void MemoryCounter::update_peak(size_t size, size_t cnt) { size_t peak_sz = peak_size(); while (peak_sz < size) { @@ -59,7 +58,6 @@ } } } -#endif // ASSERT // Total malloc'd memory used by arenas size_t MallocMemorySnapshot::total_arena() const { @@ -213,7 +211,8 @@ const uint8_t* here = align_down(addr, smallest_possible_alignment); const uint8_t* const end = here - (0x1000 + sizeof(MallocHeader)); // stop searching after 4k for (; here >= end; here -= smallest_possible_alignment) { - if (!os::is_readable_pointer(here)) { + // JDK-8306561: cast to a MallocHeader needs to guarantee it can reside in readable memory + if (!os::is_readable_range(here, here + sizeof(MallocHeader))) { // Probably OOB, give up break; } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/mallocTracker.hpp openjdk-21-21.0.2+13/src/hotspot/share/services/mallocTracker.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/mallocTracker.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/mallocTracker.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -46,25 +46,20 @@ volatile size_t _count; volatile size_t _size; -#ifdef ASSERT // Peak size and count. Note: Peak count is the count at the point // peak size was reached, not the absolute highest peak count. volatile size_t _peak_count; volatile size_t _peak_size; void update_peak(size_t size, size_t cnt); -#endif // ASSERT public: - MemoryCounter() : _count(0), _size(0) { - DEBUG_ONLY(_peak_count = 0;) - DEBUG_ONLY(_peak_size = 0;) - } + MemoryCounter() : _count(0), _size(0), _peak_count(0), _peak_size(0) {} inline void allocate(size_t sz) { size_t cnt = Atomic::add(&_count, size_t(1), memory_order_relaxed); if (sz > 0) { size_t sum = Atomic::add(&_size, sz, memory_order_relaxed); - DEBUG_ONLY(update_peak(sum, cnt);) + update_peak(sum, cnt); } } @@ -81,7 +76,7 @@ if (sz != 0) { assert(sz >= 0 || size() >= size_t(-sz), "Must be"); size_t sum = Atomic::add(&_size, size_t(sz), memory_order_relaxed); - DEBUG_ONLY(update_peak(sum, _count);) + update_peak(sum, _count); } } @@ -89,11 +84,11 @@ inline size_t size() const { return Atomic::load(&_size); } inline size_t peak_count() const { - return DEBUG_ONLY(Atomic::load(&_peak_count)) NOT_DEBUG(0); + return Atomic::load(&_peak_count); } inline size_t peak_size() const { - return DEBUG_ONLY(Atomic::load(&_peak_size)) NOT_DEBUG(0); + return Atomic::load(&_peak_size); } }; @@ -181,11 +176,6 @@ // Total malloc'd memory used by arenas size_t total_arena() const; - inline size_t thread_count() const { - MallocMemorySnapshot* s = const_cast(this); - return s->by_type(mtThreadStack)->malloc_count(); - } - void copy_to(MallocMemorySnapshot* s) { // Need to make sure that mtChunks don't get deallocated while the // copy is going on, because their size is adjusted using this diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/memBaseline.cpp openjdk-21-21.0.2+13/src/hotspot/share/services/memBaseline.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/memBaseline.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/memBaseline.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -190,6 +190,7 @@ _instance_class_count = ClassLoaderDataGraph::num_instance_classes(); _array_class_count = ClassLoaderDataGraph::num_array_classes(); + _thread_count = ThreadStackTracker::thread_count(); baseline_summary(); _baseline_type = Summary_baselined; diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/memBaseline.hpp openjdk-21-21.0.2+13/src/hotspot/share/services/memBaseline.hpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/memBaseline.hpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/memBaseline.hpp 2024-01-16 16:19:00.000000000 +0000 @@ -64,6 +64,7 @@ size_t _instance_class_count; size_t _array_class_count; + size_t _thread_count; // Allocation sites information // Malloc allocation sites @@ -84,7 +85,7 @@ public: // create a memory baseline MemBaseline(): - _instance_class_count(0), _array_class_count(0), + _instance_class_count(0), _array_class_count(0), _thread_count(0), _baseline_type(Not_baselined) { } @@ -171,7 +172,7 @@ size_t thread_count() const { assert(baseline_type() != Not_baselined, "Not yet baselined"); - return _malloc_memory_snapshot.thread_count(); + return _thread_count; } // reset the baseline for reuse @@ -180,6 +181,7 @@ // _malloc_memory_snapshot and _virtual_memory_snapshot are copied over. _instance_class_count = 0; _array_class_count = 0; + _thread_count = 0; _malloc_sites.clear(); _virtual_memory_sites.clear(); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/memReporter.cpp openjdk-21-21.0.2+13/src/hotspot/share/services/memReporter.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/memReporter.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/memReporter.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -233,7 +233,6 @@ MallocMemory* thread_stack_memory = _malloc_snapshot->by_type(mtThreadStack); const char* scale = current_scale(); // report thread count - assert(ThreadStackTracker::thread_count() == 0, "Not used"); out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", thread_stack_memory->malloc_count()); out->print("%27s (Stack: " SIZE_FORMAT "%s", " ", amount_in_current_scale(thread_stack_memory->malloc_size()), scale); @@ -243,7 +242,7 @@ // report malloc'd memory if (amount_in_current_scale(malloc_memory->malloc_size()) > 0 - DEBUG_ONLY(|| amount_in_current_scale(malloc_memory->malloc_peak_size()) > 0)) { + || amount_in_current_scale(malloc_memory->malloc_peak_size()) > 0) { print_malloc_line(malloc_memory->malloc_counter()); } diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/nmtDCmd.cpp openjdk-21-21.0.2+13/src/hotspot/share/services/nmtDCmd.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/nmtDCmd.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/nmtDCmd.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -77,7 +77,7 @@ return; } - const char* scale_value = _scale.value(); + const char* scale_value = _scale.value() != nullptr ? _scale.value() : "(null)"; size_t scale_unit = get_scale(scale_value); if (scale_unit == 0) { output()->print_cr("Incorrect scale value: %s", scale_value); diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/services/threadStackTracker.cpp openjdk-21-21.0.2+13/src/hotspot/share/services/threadStackTracker.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/services/threadStackTracker.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/services/threadStackTracker.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -49,40 +49,38 @@ void ThreadStackTracker::new_thread_stack(void* base, size_t size, const NativeCallStack& stack) { assert(MemTracker::tracking_level() >= NMT_summary, "Must be"); assert(base != nullptr, "Should have been filtered"); + ThreadCritical tc; if (track_as_vm()) { - ThreadCritical tc; VirtualMemoryTracker::add_reserved_region((address)base, size, stack, mtThreadStack); - _thread_count ++; } else { // Use a slot in mallocMemorySummary for thread stack bookkeeping MallocMemorySummary::record_malloc(size, mtThreadStack); if (MemTracker::tracking_level() == NMT_detail) { - ThreadCritical tc; assert(_simple_thread_stacks != nullptr, "Must be initialized"); SimpleThreadStackSite site((address)base, size, stack); _simple_thread_stacks->add(site); } } + _thread_count++; } void ThreadStackTracker::delete_thread_stack(void* base, size_t size) { assert(MemTracker::tracking_level() >= NMT_summary, "Must be"); assert(base != nullptr, "Should have been filtered"); + ThreadCritical tc; if(track_as_vm()) { - ThreadCritical tc; VirtualMemoryTracker::remove_released_region((address)base, size); - _thread_count--; } else { // Use a slot in mallocMemorySummary for thread stack bookkeeping MallocMemorySummary::record_free(size, mtThreadStack); if (MemTracker::tracking_level() == NMT_detail) { - ThreadCritical tc; assert(_simple_thread_stacks != nullptr, "Must be initialized"); SimpleThreadStackSite site((address)base, size, NativeCallStack::empty_stack()); // Fake object just to serve as compare target for delete bool removed = _simple_thread_stacks->remove(site); assert(removed, "Must exist"); } } + _thread_count--; } bool ThreadStackTracker::walk_simple_thread_stack_site(MallocSiteWalker* walker) { diff -Nru openjdk-21-21.0.1+12/src/hotspot/share/utilities/vmError.cpp openjdk-21-21.0.2+13/src/hotspot/share/utilities/vmError.cpp --- openjdk-21-21.0.1+12/src/hotspot/share/utilities/vmError.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/hotspot/share/utilities/vmError.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -74,6 +74,10 @@ #include "jvmci/jvmci.hpp" #endif +#ifdef AIX +#include "loadlib_aix.hpp" +#endif + #ifndef PRODUCT #include #endif // PRODUCT @@ -1094,6 +1098,11 @@ print_stack_location(st, _context, continuation); st->cr(); + STEP_IF("printing lock stack", _verbose && _thread != nullptr && _thread->is_Java_thread() && LockingMode == LM_LIGHTWEIGHT); + st->print_cr("Lock stack of current Java thread (top to bottom):"); + JavaThread::cast(_thread)->lock_stack().print_on(st); + st->cr(); + STEP_IF("printing code blobs if possible", _verbose) const int printed_capacity = max_error_log_print_code; address printed[printed_capacity]; @@ -1332,6 +1341,8 @@ void VMError::print_vm_info(outputStream* st) { char buf[O_BUFLEN]; + AIX_ONLY(LoadedLibraries::reload()); + report_vm_version(st, buf, sizeof(buf)); // STEP("printing summary") diff -Nru openjdk-21-21.0.1+12/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c openjdk-21-21.0.2+13/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c --- openjdk-21-21.0.1+12/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -24,10 +24,12 @@ */ #include "jni.h" +#include "jni_util.h" #include "ProcessHandleImpl_unix.h" #include +#include /* * Implementation of native ProcessHandleImpl functions for AIX. @@ -36,9 +38,127 @@ void os_initNative(JNIEnv *env, jclass clazz) {} +/* + * Return pids of active processes, and optionally parent pids and + * start times for each process. + * For a specific non-zero pid, only the direct children are returned. + * If the pid is zero, all active processes are returned. + * Use getprocs64 to accumulate any process following the rules above. + * The resulting pids are stored into an array of longs named jarray. + * The number of pids is returned if they all fit. + * If the parentArray is non-null, store also the parent pid. + * In this case the parentArray must have the same length as the result pid array. + * Of course in the case of a given non-zero pid all entries in the parentArray + * will contain this pid, so this array does only make sense in the case of a given + * zero pid. + * If the jstimesArray is non-null, store also the start time of the pid. + * In this case the jstimesArray must have the same length as the result pid array. + * If the array(s) (is|are) too short, excess pids are not stored and + * the desired length is returned. + */ jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, jlongArray jparentArray, jlongArray jstimesArray) { - return unix_getChildren(env, jpid, jarray, jparentArray, jstimesArray); + pid_t pid = (pid_t) jpid; + jlong* pids = NULL; + jlong* ppids = NULL; + jlong* stimes = NULL; + jsize parentArraySize = 0; + jsize arraySize = 0; + jsize stimesSize = 0; + jsize count = 0; + + arraySize = (*env)->GetArrayLength(env, jarray); + JNU_CHECK_EXCEPTION_RETURN(env, -1); + if (jparentArray != NULL) { + parentArraySize = (*env)->GetArrayLength(env, jparentArray); + JNU_CHECK_EXCEPTION_RETURN(env, -1); + + if (arraySize != parentArraySize) { + JNU_ThrowIllegalArgumentException(env, "array sizes not equal"); + return 0; + } + } + if (jstimesArray != NULL) { + stimesSize = (*env)->GetArrayLength(env, jstimesArray); + JNU_CHECK_EXCEPTION_RETURN(env, -1); + + if (arraySize != stimesSize) { + JNU_ThrowIllegalArgumentException(env, "array sizes not equal"); + return 0; + } + } + + const int chunk = 100; + struct procentry64 ProcessBuffer[chunk]; + pid_t idxptr = 0; + int i, num = 0; + + do { // Block to break out of on Exception + pids = (*env)->GetLongArrayElements(env, jarray, NULL); + if (pids == NULL) { + break; + } + if (jparentArray != NULL) { + ppids = (*env)->GetLongArrayElements(env, jparentArray, NULL); + if (ppids == NULL) { + break; + } + } + if (jstimesArray != NULL) { + stimes = (*env)->GetLongArrayElements(env, jstimesArray, NULL); + if (stimes == NULL) { + break; + } + } + + while ((num = getprocs64(ProcessBuffer, sizeof(struct procentry64), NULL, + sizeof(struct fdsinfo64), &idxptr, chunk)) != -1) { + for (i = 0; i < num; i++) { + pid_t childpid = (pid_t) ProcessBuffer[i].pi_pid; + pid_t ppid = (pid_t) ProcessBuffer[i].pi_ppid; + + // Get the parent pid, and start time + if (pid == 0 || ppid == pid) { + if (count < arraySize) { + // Only store if it fits + pids[count] = (jlong) childpid; + + if (ppids != NULL) { + // Store the parentPid + ppids[count] = (jlong) ppid; + } + if (stimes != NULL) { + // Store the process start time + stimes[count] = ((jlong) ProcessBuffer[i].pi_start) * 1000;; + } + } + count++; // Count to tabulate size needed + } + } + if (num < chunk) { + break; + } + } + } while (0); + + if (pids != NULL) { + (*env)->ReleaseLongArrayElements(env, jarray, pids, 0); + } + if (ppids != NULL) { + (*env)->ReleaseLongArrayElements(env, jparentArray, ppids, 0); + } + if (stimes != NULL) { + (*env)->ReleaseLongArrayElements(env, jstimesArray, stimes, 0); + } + + if (num == -1) { + JNU_ThrowByNameWithLastError(env, + "java/lang/RuntimeException", "Unable to retrieve Process info"); + return -1; + } + + // If more pids than array had size for; count will be greater than array size + return count; } pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *start) { diff -Nru openjdk-21-21.0.1+12/src/java.base/aix/native/libnio/MappedMemoryUtils.c openjdk-21-21.0.2+13/src/java.base/aix/native/libnio/MappedMemoryUtils.c --- openjdk-21-21.0.1+12/src/java.base/aix/native/libnio/MappedMemoryUtils.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/aix/native/libnio/MappedMemoryUtils.c 2024-01-16 16:19:00.000000000 +0000 @@ -158,6 +158,11 @@ FILE* proc_file; { char* fname = (char*) malloc(sizeof(char) * PFNAME_LEN); + if (fname == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return; + } + pid_t the_pid = getpid(); jio_snprintf(fname, PFNAME_LEN, "/proc/%d/map", the_pid); proc_file = fopen(fname, "r"); @@ -170,6 +175,11 @@ } { prmap_t* map_entry = (prmap_t*) malloc(sizeof(prmap_t)); + if (map_entry == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + fclose(proc_file); + return; + } check_proc_map_array(env, proc_file, map_entry, end_address); free(map_entry); } diff -Nru openjdk-21-21.0.1+12/src/java.base/aix/native/libnio/fs/AixNativeDispatcher.c openjdk-21-21.0.2+13/src/java.base/aix/native/libnio/fs/AixNativeDispatcher.c --- openjdk-21-21.0.1+12/src/java.base/aix/native/libnio/fs/AixNativeDispatcher.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/aix/native/libnio/fs/AixNativeDispatcher.c 2024-01-16 16:19:00.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, 2019 SAP SE. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -105,6 +105,10 @@ } buffer_size *= 8; buffer = malloc(buffer_size); + if (buffer == NULL) { + throwUnixException(env, errno); + return NULL; + } must_free_buf = 1; } /* Treat zero entries like errors. */ diff -Nru openjdk-21-21.0.1+12/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c openjdk-21-21.0.2+13/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c --- openjdk-21-21.0.1+12/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c 2024-01-16 16:19:00.000000000 +0000 @@ -47,13 +47,21 @@ void os_initNative(JNIEnv *env, jclass clazz) {} /* - * Returns the children of the requested pid and optionally each parent. - * - * Use sysctl to accumulate any process whose parent pid is zero or matches. - * The resulting pids are stored into the array of longs. + * Return pids of active processes, and optionally parent pids and + * start times for each process. + * For a specific non-zero pid jpid, only the direct children are returned. + * If the pid jpid is zero, all active processes are returned. + * Uses sysctl to accumulates any process following the rules above. + * The resulting pids are stored into an array of longs named jarray. * The number of pids is returned if they all fit. - * If the parentArray is non-null, store the parent pid. - * If the array is too short, excess pids are not stored and + * If the parentArray is non-null, store also the parent pid. + * In this case the parentArray must have the same length as the result pid array. + * Of course in the case of a given non-zero pid all entries in the parentArray + * will contain this pid, so this array does only make sense in the case of a given + * zero pid. + * If the jstimesArray is non-null, store also the start time of the pid. + * In this case the jstimesArray must have the same length as the result pid array. + * If the array(s) (is|are) too short, excess pids are not stored and * the desired length is returned. */ jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java openjdk-21-21.0.2+13/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java 2024-01-16 16:19:00.000000000 +0000 @@ -1572,6 +1572,13 @@ len += buffer.remaining(); } + // Check that input data is long enough to fit the expected tag. + if (len < 0) { + throw new AEADBadTagException("Input data too short to " + + "contain an expected tag length of " + tagLenBytes + + "bytes"); + } + checkDataLength(len); // Verify dst is large enough diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java openjdk-21-21.0.2+13/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java 2024-01-16 16:19:00.000000000 +0000 @@ -98,6 +98,7 @@ // cipher parameter for OAEP padding and TLS RSA premaster secret private AlgorithmParameterSpec spec = null; + private boolean forTlsPremasterSecret = false; // buffer for the data private byte[] buffer; @@ -286,6 +287,7 @@ } spec = params; + forTlsPremasterSecret = true; this.random = random; // for TLS RSA premaster secret } int blockType = (mode <= MODE_DECRYPT) ? RSAPadding.PAD_BLOCKTYPE_2 @@ -377,7 +379,7 @@ byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs); paddingCopy = RSACore.rsa(decryptBuffer, privateKey, false); result = padding.unpad(paddingCopy); - if (result == null) { + if (result == null && !forTlsPremasterSecret) { throw new BadPaddingException ("Padding error in decryption"); } @@ -466,26 +468,22 @@ boolean isTlsRsaPremasterSecret = algorithm.equals("TlsRsaPremasterSecret"); - Exception failover = null; byte[] encoded = null; update(wrappedKey, 0, wrappedKey.length); try { encoded = doFinal(); - } catch (BadPaddingException e) { - if (isTlsRsaPremasterSecret) { - failover = e; - } else { - throw new InvalidKeyException("Unwrapping failed", e); - } - } catch (IllegalBlockSizeException e) { - // should not occur, handled with length check above + } catch (BadPaddingException | IllegalBlockSizeException e) { + // BadPaddingException cannot happen for TLS RSA unwrap. + // In that case, padding error is indicated by returning null. + // IllegalBlockSizeException cannot happen in any case, + // because of the length check above. throw new InvalidKeyException("Unwrapping failed", e); } try { if (isTlsRsaPremasterSecret) { - if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { + if (!forTlsPremasterSecret) { throw new IllegalStateException( "No TlsRsaPremasterSecretParameterSpec specified"); } @@ -494,7 +492,7 @@ encoded = KeyUtil.checkTlsPreMasterSecretKey( ((TlsRsaPremasterSecretParameterSpec) spec).getClientVersion(), ((TlsRsaPremasterSecretParameterSpec) spec).getServerVersion(), - random, encoded, (failover != null)); + random, encoded, encoded == null); } return ConstructKeys.constructKey(encoded, algorithm, type); diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/io/ByteArrayInputStream.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/io/ByteArrayInputStream.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/io/ByteArrayInputStream.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/io/ByteArrayInputStream.java 2024-01-16 16:19:00.000000000 +0000 @@ -44,6 +44,7 @@ * @since 1.0 */ public class ByteArrayInputStream extends InputStream { + private static final int MAX_TRANSFER_SIZE = 128*1024; /** * An array of bytes that was provided @@ -205,8 +206,16 @@ @Override public synchronized long transferTo(OutputStream out) throws IOException { int len = count - pos; - out.write(buf, pos, len); - pos = count; + if (len > 0) { + int nwritten = 0; + while (nwritten < len) { + int nbyte = Integer.min(len - nwritten, MAX_TRANSFER_SIZE); + out.write(buf, pos, nbyte); + pos += nbyte; + nwritten += nbyte; + } + assert pos == count; + } return len; } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Byte.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Byte.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Byte.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Byte.java 2024-01-16 16:19:00.000000000 +0000 @@ -27,6 +27,7 @@ import jdk.internal.misc.CDS; import jdk.internal.vm.annotation.IntrinsicCandidate; +import jdk.internal.vm.annotation.Stable; import java.lang.constant.Constable; import java.lang.constant.DynamicConstantDesc; @@ -105,9 +106,10 @@ return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_byte, intValue())); } - private static class ByteCache { + private static final class ByteCache { private ByteCache() {} + @Stable static final Byte[] cache; static Byte[] archivedCache; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Character.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Character.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Character.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Character.java 2024-01-16 16:19:00.000000000 +0000 @@ -27,6 +27,7 @@ import jdk.internal.misc.CDS; import jdk.internal.vm.annotation.IntrinsicCandidate; +import jdk.internal.vm.annotation.Stable; import java.lang.constant.Constable; import java.lang.constant.DynamicConstantDesc; @@ -8956,9 +8957,10 @@ this.value = value; } - private static class CharacterCache { + private static final class CharacterCache { private CharacterCache(){} + @Stable static final Character[] cache; static Character[] archivedCache; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Integer.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Integer.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Integer.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Integer.java 2024-01-16 16:19:00.000000000 +0000 @@ -29,6 +29,7 @@ import jdk.internal.misc.VM; import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.IntrinsicCandidate; +import jdk.internal.vm.annotation.Stable; import java.lang.annotation.Native; import java.lang.constant.Constable; @@ -1005,9 +1006,11 @@ * with new Integer object(s) after initialization. */ - private static class IntegerCache { + private static final class IntegerCache { static final int low = -128; static final int high; + + @Stable static final Integer[] cache; static Integer[] archivedCache; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Long.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Long.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Long.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Long.java 2024-01-16 16:19:00.000000000 +0000 @@ -36,6 +36,7 @@ import jdk.internal.misc.CDS; import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.IntrinsicCandidate; +import jdk.internal.vm.annotation.Stable; import static java.lang.String.COMPACT_STRINGS; import static java.lang.String.LATIN1; @@ -1156,9 +1157,10 @@ return Long.valueOf(parseLong(s, 10)); } - private static class LongCache { + private static final class LongCache { private LongCache() {} + @Stable static final Long[] cache; static Long[] archivedCache; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/ScopedValue.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/ScopedValue.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/ScopedValue.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/ScopedValue.java 2024-01-16 16:19:00.000000000 +0000 @@ -787,7 +787,8 @@ // Bindings can be in one of four states: // // 1: class Thread: this is a new Thread instance, and no - // scoped values have ever been bound in this Thread. + // scoped values have ever been bound in this Thread, and neither + // have any scoped value bindings been inherited from a parent. // 2: EmptySnapshot.SINGLETON: This is effectively an empty binding. // 3: A Snapshot instance: this contains one or more scoped value // bindings. @@ -798,18 +799,18 @@ Object bindings = Thread.scopedValueBindings(); if (bindings == NEW_THREAD_BINDINGS) { // This must be a new thread - return Snapshot.EMPTY_SNAPSHOT; + return Snapshot.EMPTY_SNAPSHOT; } if (bindings == null) { // Search the stack bindings = Thread.findScopedValueBindings(); - if (bindings == null) { - // Nothing on the stack. + if (bindings == NEW_THREAD_BINDINGS || bindings == null) { + // We've walked the stack without finding anything. bindings = Snapshot.EMPTY_SNAPSHOT; } + Thread.setScopedValueBindings(bindings); } assert (bindings != null); - Thread.setScopedValueBindings(bindings); return (Snapshot) bindings; } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Short.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Short.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/Short.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/Short.java 2024-01-16 16:19:00.000000000 +0000 @@ -27,6 +27,7 @@ import jdk.internal.misc.CDS; import jdk.internal.vm.annotation.IntrinsicCandidate; +import jdk.internal.vm.annotation.Stable; import java.lang.constant.Constable; import java.lang.constant.DynamicConstantDesc; @@ -231,9 +232,10 @@ return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_short, intValue())); } - private static class ShortCache { + private static final class ShortCache { private ShortCache() {} + @Stable static final Short[] cache; static Short[] archivedCache; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/String.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/String.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/String.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/String.java 2024-01-16 16:19:00.000000000 +0000 @@ -2156,6 +2156,10 @@ (ooffset > (long)other.length() - len)) { return false; } + // Any strings match if len <= 0 + if (len <= 0) { + return true; + } byte[] tv = value; byte[] ov = other.value; byte coder = coder(); diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/System.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/System.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/System.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/System.java 2024-01-16 16:19:00.000000000 +0000 @@ -68,6 +68,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; +import jdk.internal.logger.LoggerFinderLoader.TemporaryLoggerFinder; import jdk.internal.misc.CarrierThreadLocal; import jdk.internal.misc.Unsafe; import jdk.internal.util.StaticProperty; @@ -1766,13 +1767,16 @@ // We do not need to synchronize: LoggerFinderLoader will // always return the same instance, so if we don't have it, // just fetch it again. - if (service == null) { + LoggerFinder finder = service; + if (finder == null) { PrivilegedAction pa = () -> LoggerFinderLoader.getLoggerFinder(); - service = AccessController.doPrivileged(pa, null, + finder = AccessController.doPrivileged(pa, null, LOGGERFINDER_PERMISSION); + if (finder instanceof TemporaryLoggerFinder) return finder; + service = finder; } - return service; + return finder; } } @@ -2666,7 +2670,7 @@ } public String getLoaderNameID(ClassLoader loader) { - return loader.nameAndId(); + return loader != null ? loader.nameAndId() : "null"; } }); } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/VirtualThread.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/VirtualThread.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/VirtualThread.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/VirtualThread.java 2024-01-16 16:19:00.000000000 +0000 @@ -630,10 +630,8 @@ // park on carrier thread for remaining time when pinned if (!yielded) { - long deadline = startTime + nanos; - if (deadline < 0L) - deadline = Long.MAX_VALUE; - parkOnCarrierThread(true, deadline - System.nanoTime()); + long remainingNanos = nanos - (System.nanoTime() - startTime); + parkOnCarrierThread(true, remainingNanos); } } } @@ -864,13 +862,14 @@ @Override boolean getAndClearInterrupt() { assert Thread.currentThread() == this; - synchronized (interruptLock) { - boolean oldValue = interrupted; - if (oldValue) + boolean oldValue = interrupted; + if (oldValue) { + synchronized (interruptLock) { interrupted = false; - carrierThread.clearInterrupt(); - return oldValue; + carrierThread.clearInterrupt(); + } } + return oldValue; } @Override diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/invoke/MethodHandle.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/invoke/MethodHandle.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/invoke/MethodHandle.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/invoke/MethodHandle.java 2024-01-16 16:19:00.000000000 +0000 @@ -1719,7 +1719,8 @@ try { return this.withVarargs(true); } catch (IllegalArgumentException ex) { - throw member.makeAccessException("cannot make variable arity", null); + throw new IllegalAccessException("cannot make variable arity: " + member + + " does not have a trailing array parameter"); } } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java 2024-01-16 16:19:00.000000000 +0000 @@ -394,9 +394,13 @@ Object resolved; try { + if (!(value instanceof Enum enumValue)) { + return false; + } + Class clazz = label.constantType().resolveConstantDesc(lookup); - if (value.getClass() != clazz) { + if (enumValue.getDeclaringClass() != clazz) { return false; } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template openjdk-21-21.0.2+13/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template 2024-01-16 16:19:00.000000000 +0000 @@ -75,31 +75,15 @@ #if[byte] - private static class Deallocator - implements Runnable - { - - private long address; - private long size; - private int capacity; - - private Deallocator(long address, long size, int capacity) { - assert (address != 0); - this.address = address; - this.size = size; - this.capacity = capacity; + private record Deallocator(long address, long size, int capacity) implements Runnable { + private Deallocator { + assert address != 0; } public void run() { - if (address == 0) { - // Paranoia - return; - } UNSAFE.freeMemory(address); - address = 0; Bits.unreserveMemory(size, capacity); } - } private final Cleaner cleaner; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/nio/MappedByteBuffer.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/nio/MappedByteBuffer.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/nio/MappedByteBuffer.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/nio/MappedByteBuffer.java 2024-01-16 16:19:00.000000000 +0000 @@ -116,28 +116,33 @@ } UnmapperProxy unmapper() { - return fd != null ? - new UnmapperProxy() { - @Override - public long address() { - return address; - } - - @Override - public FileDescriptor fileDescriptor() { - return fd; - } - - @Override - public boolean isSync() { - return isSync; - } - - @Override - public void unmap() { - Unsafe.getUnsafe().invokeCleaner(MappedByteBuffer.this); - } - } : null; + return fd == null + ? null + : new UnmapperProxy() { + + // Ensure safe publication as MappedByteBuffer.this.address is not final + private final long addr = address; + + @Override + public long address() { + return addr; + } + + @Override + public FileDescriptor fileDescriptor() { + return fd; + } + + @Override + public boolean isSync() { + return isSync; + } + + @Override + public void unmap() { + Unsafe.getUnsafe().invokeCleaner(MappedByteBuffer.this); + } + }; } /** diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java 2024-01-16 16:19:00.000000000 +0000 @@ -47,6 +47,7 @@ import java.util.Spliterator; import java.util.Spliterators; import java.util.concurrent.locks.LockSupport; +import java.util.concurrent.ForkJoinWorkerThread; import java.util.function.Consumer; import java.util.function.Predicate; @@ -107,7 +108,11 @@ * http://www.cs.rochester.edu/u/scott/papers/2009_Scherer_CACM_SSQ.pdf) * additionally arrange that threads enqueuing unmatched data also * block. Dual Transfer Queues support all of these modes, as - * dictated by callers. + * dictated by callers. All enqueue/dequeue operations can be + * handled by a single method (here, "xfer") with parameters + * indicating whether to act as some form of offer, put, poll, + * take, or transfer (each possibly with timeout), as described + * below. * * A FIFO dual queue may be implemented using a variation of the * Michael & Scott (M&S) lock-free queue algorithm @@ -126,44 +131,33 @@ * * The M&S queue algorithm is known to be prone to scalability and * overhead limitations when maintaining (via CAS) these head and - * tail pointers. This has led to the development of - * contention-reducing variants such as elimination arrays (see - * Moir et al http://portal.acm.org/citation.cfm?id=1074013) and - * optimistic back pointers (see Ladan-Mozes & Shavit - * http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf). - * However, the nature of dual queues enables a simpler tactic for - * improving M&S-style implementations when dual-ness is needed. + * tail pointers. To address these, dual queues with slack differ + * from plain M&S dual queues by virtue of only sometimes updating + * head or tail pointers when matching, appending, or even + * traversing nodes. * * In a dual queue, each node must atomically maintain its match - * status. While there are other possible variants, we implement - * this here as: for a data-mode node, matching entails CASing an - * "item" field from a non-null data value to null upon match, and - * vice-versa for request nodes, CASing from null to a data - * value. (Note that the linearization properties of this style of - * queue are easy to verify -- elements are made available by - * linking, and unavailable by matching.) Compared to plain M&S - * queues, this property of dual queues requires one additional - * successful atomic operation per enq/deq pair. But it also - * enables lower cost variants of queue maintenance mechanics. (A - * variation of this idea applies even for non-dual queues that - * support deletion of interior elements, such as - * j.u.c.ConcurrentLinkedQueue.) - * - * Once a node is matched, its match status can never again - * change. We may thus arrange that the linked list of them - * contain a prefix of zero or more matched nodes, followed by a - * suffix of zero or more unmatched nodes. (Note that we allow - * both the prefix and suffix to be zero length, which in turn - * means that we do not use a dummy header.) If we were not - * concerned with either time or space efficiency, we could - * correctly perform enqueue and dequeue operations by traversing - * from a pointer to the initial node; CASing the item of the - * first unmatched node on match and CASing the next field of the - * trailing node on appends. While this would be a terrible idea - * in itself, it does have the benefit of not requiring ANY atomic - * updates on head/tail fields. + * status. Matching entails CASing an "item" field from a non-null + * data value to null upon match, and vice-versa for request + * nodes, CASing from null to a data value. (To reduce the need + * for re-reads, we use the compareAndExchange forms of CAS for + * pointer updates, that provide the current value to continue + * with on failure.) Note that the linearization properties of + * this style of queue are easy to verify -- elements are made + * available by linking, and unavailable by matching. Compared to + * plain M&S queues, this property of dual queues requires one + * additional successful atomic operation per enq/deq pair. But it + * also enables lower cost variants of queue maintenance + * mechanics. + * + * Once a node is matched, it is no longer live -- its match + * status can never again change. We may thus arrange that the + * linked list of them contain a prefix of zero or more dead + * nodes, followed by a suffix of zero or more live nodes. Note + * that we allow both the prefix and suffix to be zero length, + * which in turn means that we do not require a dummy header. * - * We introduce here an approach that lies between the extremes of + * We use here an approach that lies between the extremes of * never versus always updating queue (head and tail) pointers. * This offers a tradeoff between sometimes requiring extra * traversal steps to locate the first and/or last unmatched @@ -178,143 +172,43 @@ * * The best value for this "slack" (the targeted maximum distance * between the value of "head" and the first unmatched node, and - * similarly for "tail") is an empirical matter. We have found - * that using very small constants in the range of 1-3 work best - * over a range of platforms. Larger values introduce increasing - * costs of cache misses and risks of long traversal chains, while - * smaller values increase CAS contention and overhead. - * - * Dual queues with slack differ from plain M&S dual queues by - * virtue of only sometimes updating head or tail pointers when - * matching, appending, or even traversing nodes; in order to - * maintain a targeted slack. The idea of "sometimes" may be - * operationalized in several ways. The simplest is to use a - * per-operation counter incremented on each traversal step, and - * to try (via CAS) to update the associated queue pointer - * whenever the count exceeds a threshold. Another, that requires - * more overhead, is to use random number generators to update - * with a given probability per traversal step. - * - * In any strategy along these lines, because CASes updating - * fields may fail, the actual slack may exceed targeted slack. - * However, they may be retried at any time to maintain targets. - * Even when using very small slack values, this approach works - * well for dual queues because it allows all operations up to the - * point of matching or appending an item (hence potentially - * allowing progress by another thread) to be read-only, thus not - * introducing any further contention. As described below, we - * implement this by performing slack maintenance retries only - * after these points. - * - * As an accompaniment to such techniques, traversal overhead can - * be further reduced without increasing contention of head - * pointer updates: Threads may sometimes shortcut the "next" link - * path from the current "head" node to be closer to the currently - * known first unmatched node, and similarly for tail. Again, this - * may be triggered with using thresholds or randomization. + * similarly for "tail") is an empirical matter. Larger values + * introduce increasing costs of cache misses and risks of long + * traversal chains and out-of-order updates, while smaller values + * increase CAS contention and overhead. Using the smallest + * non-zero value of one is both simple and empirically a good + * choice in most applicatkions. The slack value is hard-wired: a + * path greater than one is usually implemented by checking + * equality of traversal pointers. Because CASes updating fields + * attempting to do so may stall, the writes may appear out of + * order (an older CAS from the same head or tail may execute + * after a newer one), the actual slack may exceed targeted + * slack. To reduce impact, other threads may help update by + * unsplicing dead nodes while traversing. * * These ideas must be further extended to avoid unbounded amounts * of costly-to-reclaim garbage caused by the sequential "next" * links of nodes starting at old forgotten head nodes: As first * described in detail by Boehm - * (http://portal.acm.org/citation.cfm?doid=503272.503282), if a GC - * delays noticing that any arbitrarily old node has become + * (http://portal.acm.org/citation.cfm?doid=503272.503282), if a + * GC delays noticing that any arbitrarily old node has become * garbage, all newer dead nodes will also be unreclaimed. * (Similar issues arise in non-GC environments.) To cope with - * this in our implementation, upon CASing to advance the head - * pointer, we set the "next" link of the previous head to point - * only to itself; thus limiting the length of chains of dead nodes. - * (We also take similar care to wipe out possibly garbage - * retaining values held in other Node fields.) However, doing so - * adds some further complexity to traversal: If any "next" - * pointer links to itself, it indicates that the current thread - * has lagged behind a head-update, and so the traversal must - * continue from the "head". Traversals trying to find the - * current tail starting from "tail" may also encounter - * self-links, in which case they also continue at "head". - * - * It is tempting in slack-based scheme to not even use CAS for - * updates (similarly to Ladan-Mozes & Shavit). However, this - * cannot be done for head updates under the above link-forgetting - * mechanics because an update may leave head at a detached node. - * And while direct writes are possible for tail updates, they - * increase the risk of long retraversals, and hence long garbage - * chains, which can be much more costly than is worthwhile - * considering that the cost difference of performing a CAS vs - * write is smaller when they are not triggered on each operation - * (especially considering that writes and CASes equally require - * additional GC bookkeeping ("write barriers") that are sometimes - * more costly than the writes themselves because of contention). - * - * *** Overview of implementation *** - * - * We use a threshold-based approach to updates, with a slack - * threshold of two -- that is, we update head/tail when the - * current pointer appears to be two or more steps away from the - * first/last node. The slack value is hard-wired: a path greater - * than one is naturally implemented by checking equality of - * traversal pointers except when the list has only one element, - * in which case we keep slack threshold at one. Avoiding tracking - * explicit counts across method calls slightly simplifies an - * already-messy implementation. Using randomization would - * probably work better if there were a low-quality dirt-cheap - * per-thread one available, but even ThreadLocalRandom is too - * heavy for these purposes. - * - * With such a small slack threshold value, it is not worthwhile - * to augment this with path short-circuiting (i.e., unsplicing - * interior nodes) except in the case of cancellation/removal (see - * below). - * - * All enqueue/dequeue operations are handled by the single method - * "xfer" with parameters indicating whether to act as some form - * of offer, put, poll, take, or transfer (each possibly with - * timeout). The relative complexity of using one monolithic - * method outweighs the code bulk and maintenance problems of - * using separate methods for each case. - * - * Operation consists of up to two phases. The first is implemented - * in method xfer, the second in method awaitMatch. - * - * 1. Traverse until matching or appending (method xfer) - * - * Conceptually, we simply traverse all nodes starting from head. - * If we encounter an unmatched node of opposite mode, we match - * it and return, also updating head (by at least 2 hops) to - * one past the matched node (or the node itself if it's the - * pinned trailing node). Traversals also check for the - * possibility of falling off-list, in which case they restart. - * - * If the trailing node of the list is reached, a match is not - * possible. If this call was untimed poll or tryTransfer - * (argument "how" is NOW), return empty-handed immediately. - * Else a new node is CAS-appended. On successful append, if - * this call was ASYNC (e.g. offer), an element was - * successfully added to the end of the queue and we return. - * - * Of course, this naive traversal is O(n) when no match is - * possible. We optimize the traversal by maintaining a tail - * pointer, which is expected to be "near" the end of the list. - * It is only safe to fast-forward to tail (in the presence of - * arbitrary concurrent changes) if it is pointing to a node of - * the same mode, even if it is dead (in this case no preceding - * node could still be matchable by this traversal). If we - * need to restart due to falling off-list, we can again - * fast-forward to tail, but only if it has changed since the - * last traversal (else we might loop forever). If tail cannot - * be used, traversal starts at head (but in this case we - * expect to be able to match near head). As with head, we - * CAS-advance the tail pointer by at least two hops. - * - * 2. Await match or cancellation (method awaitMatch) - * - * Wait for another thread to match node; instead cancelling if - * the current thread was interrupted or the wait timed out. To - * improve performance in common single-source / single-sink - * usages when there are more tasks that cores, an initial - * Thread.yield is tried when there is apparently only one - * waiter. In other cases, waiters may help with some - * bookkeeping, then park/unpark. + * this in our implementation, upon advancing the head pointer, we + * set the "next" link of the previous head to point only to + * itself; thus limiting the length of chains of dead nodes. (We + * also take similar care to wipe out possibly garbage retaining + * values held in other node fields.) This is easy to accommodate + * in the primary xfer method, but adds a lot of complexity to + * Collection operations including traversal; mainly because if + * any "next" pointer links to itself, the current thread has + * lagged behind a head-update, and so must restart. + * + * *** Blocking *** + * + * The DualNode class is shared with class SynchronousQueue. It + * houses method await, which is used for all blocking control, as + * described below in DualNode internal documentation. * * ** Unlinking removed interior nodes ** * @@ -330,15 +224,13 @@ * unreachable in this way: (1) If s is the trailing node of list * (i.e., with null next), then it is pinned as the target node * for appends, so can only be removed later after other nodes are - * appended. (2) We cannot necessarily unlink s given a - * predecessor node that is matched (including the case of being - * cancelled): the predecessor may already be unspliced, in which - * case some previous reachable node may still point to s. - * (For further explanation see Herlihy & Shavit "The Art of - * Multiprocessor Programming" chapter 9). Although, in both - * cases, we can rule out the need for further action if either s - * or its predecessor are (or can be made to be) at, or fall off - * from, the head of list. + * appended. (2) Unless we know it is already off-list, we cannot + * necessarily unlink s given a predecessor node that is matched + * (including the case of being cancelled): the predecessor may + * already be unspliced, in which case some previous reachable + * node may still point to s. (For further explanation see + * Herlihy & Shavit "The Art of Multiprocessor Programming" + * chapter 9). * * Without taking these into account, it would be possible for an * unbounded number of supposedly removed nodes to remain reachable. @@ -350,337 +242,472 @@ * * When these cases arise, rather than always retraversing the * entire list to find an actual predecessor to unlink (which - * won't help for case (1) anyway), we record the need to sweep the - * next time any thread would otherwise block in awaitMatch. Also, - * because traversal operations on the linked list of nodes are a - * natural opportunity to sweep dead nodes, we generally do so, - * including all the operations that might remove elements as they - * traverse, such as removeIf and Iterator.remove. This largely - * eliminates long chains of dead interior nodes, except from - * cancelled or timed out blocking operations. + * won't help for case (1) anyway), we record a conservative + * estimate of possible unsplice failures (in "sweepVotes"). + * We trigger a full sweep when the estimate exceeds a threshold + * ("SWEEP_THRESHOLD") indicating the maximum number of estimated + * removal failures to tolerate before sweeping through, unlinking + * cancelled nodes that were not unlinked upon initial removal. + * We perform sweeps by the thread hitting threshold (rather than + * background threads or by spreading work to other threads) + * because in the main contexts in which removal occurs, the + * caller is timed-out or cancelled, which are not time-critical + * enough to warrant the overhead that alternatives would impose + * on other threads. + * + * Because the sweepVotes estimate is conservative, and because + * nodes become unlinked "naturally" as they fall off the head of + * the queue, and because we allow votes to accumulate even while + * sweeps are in progress, there are typically significantly fewer + * such nodes than estimated. * * Note that we cannot self-link unlinked interior nodes during * sweeps. However, the associated garbage chains terminate when * some successor ultimately falls off the head of the list and is * self-linked. + * + * *** Revision notes *** + * + * This version differs from previous releases as follows: + * + * * Class DualNode replaces Qnode, with fields and methods + * that apply to any match-based dual data structure, and now + * usable in other j.u.c classes. in particular, SynchronousQueue. + * * Blocking control (in class DualNode) accommodates + * VirtualThreads and (perhaps virtualized) uniprocessors. + * * All fields of this class (LinkedTransferQueue) are + * default-initializable (to null), allowing further extension + * (in particular, SynchronousQueue.Transferer) + * * Head and tail fields are lazily initialized rather than set + * to a dummy node, while also reducing retries under heavy + * contention and misorderings, and relaxing some accesses, + * requiring accommodation in many places (as well as + * adjustments in WhiteBox tests). + */ + + /** + * Node for linked dual data structures. Uses type Object, not E, + * for items to allow cancellation and forgetting after use. Only + * field "item" is declared volatile (with bypasses for + * pre-publication and post-match writes), although field "next" + * is also CAS-able. Other accesses are constrained by context + * (including dependent chains of next's headed by a volatile + * read). + * + * This class also arranges blocking while awaiting matches. + * Control of blocking (and thread scheduling in general) for + * possibly-synchronous queues (and channels etc constructed + * from them) must straddle two extremes: If there are too few + * underlying cores for a fulfilling party to continue, then + * the caller must park to cause a context switch. On the + * other hand, if the queue is busy with approximately the + * same number of independent producers and consumers, then + * that context switch may cause an order-of-magnitude + * slowdown. Many cases are somewhere in-between, in which + * case threads should try spinning and then give up and + * block. We deal with this as follows: + * + * 1. Callers to method await indicate eligibility for + * spinning when the node is either the only waiting node, or + * the next matchable node is still spinning. Otherwise, the + * caller may block (almost) immediately. + * + * 2. Even if eligible to spin, a caller blocks anyway in two + * cases where it is normally best: If the thread isVirtual, + * or the system is a uniprocessor. Uniprocessor status can + * vary over time (due to virtualization at other system + * levels), but checking Runtime availableProcessors can be + * slow and may itself acquire blocking locks, so we only + * occasionally (using ThreadLocalRandom) update when an + * otherwise-eligible spin elapses. + * + * 3. When enabled, spins should be long enough to cover + * bookeeping overhead of almost-immediate fulfillments, but + * much less than the expected time of a (non-virtual) + * park/unpark context switch. The optimal value is + * unknowable, in part because the relative costs of + * Thread.onSpinWait versus park/unpark vary across platforms. + * The current value is an empirical compromise across tested + * platforms. + * + * 4. When using timed waits, callers spin instead of invoking + * timed park if the remaining time is less than the likely cost + * of park/unpark. This also avoids re-parks when timed park + * returns just barely too soon. As is the case in most j.u.c + * blocking support, untimed waits use ManagedBlockers when + * callers are ForkJoin threads, but timed waits use plain + * parkNanos, under the rationale that known-to-be transient + * blocking doesn't require compensation. (This decision should be + * revisited here and elsewhere to deal with very long timeouts.) + * + * 5. Park/unpark signalling otherwise relies on a Dekker-like + * scheme in which the caller advertises the need to unpark by + * setting its waiter field, followed by a full fence and recheck + * before actually parking. An explicit fence in used here rather + * than unnecessarily requiring volatile accesses elsewhere. This + * fence also separates accesses to field isUniprocessor. + * + * 6. To make the above work, callers must precheck that + * timeouts are not already elapsed, and that interruptible + * operations were not already interrupted on call to the + * corresponding queue operation. Cancellation on timeout or + * interrupt otherwise proceeds by trying to fulfill with an + * impossible value (which is one reason that we use Object + * types here rather than typed fields). */ - - /** - * The number of nanoseconds for which it is faster to spin - * rather than to use timed park. A rough estimate suffices. - * Using a power of two minus one simplifies some comparisons. - */ - static final long SPIN_FOR_TIMEOUT_THRESHOLD = 1023L; - - /** - * The maximum number of estimated removal failures (sweepVotes) - * to tolerate before sweeping through the queue unlinking - * cancelled nodes that were not unlinked upon initial - * removal. See above for explanation. The value must be at least - * two to avoid useless sweeps when removing trailing nodes. - */ - static final int SWEEP_THRESHOLD = 32; - - /** - * Queue nodes. Uses Object, not E, for items to allow forgetting - * them after use. Writes that are intrinsically ordered wrt - * other accesses or CASes use simple relaxed forms. - */ - static final class Node implements ForkJoinPool.ManagedBlocker { - final boolean isData; // false if this is a request node + static final class DualNode implements ForkJoinPool.ManagedBlocker { volatile Object item; // initially non-null if isData; CASed to match - volatile Node next; - volatile Thread waiter; // null when not waiting for a match + DualNode next; // accessed only in chains of volatile ops + Thread waiter; // access order constrained by context + final boolean isData; // false if this is a request node - /** - * Constructs a data node holding item if item is non-null, - * else a request node. Uses relaxed write because item can - * only be seen after piggy-backing publication via CAS. - */ - Node(Object item) { - ITEM.set(this, item); - isData = (item != null); + DualNode(Object item, boolean isData) { + ITEM.set(this, item); // relaxed write before publication + this.isData = isData; } - /** Constructs a (matched data) dummy node. */ - Node() { - isData = true; + // Atomic updates + final Object cmpExItem(Object cmp, Object val) { // try to match + return ITEM.compareAndExchange(this, cmp, val); } - - final boolean casNext(Node cmp, Node val) { - // assert val != null; - return NEXT.compareAndSet(this, cmp, val); + final DualNode cmpExNext(DualNode cmp, DualNode val) { + return (DualNode)NEXT.compareAndExchange(this, cmp, val); } - final boolean casItem(Object cmp, Object val) { - // assert isData == (cmp != null); - // assert isData == (val == null); - // assert !(cmp instanceof Node); - return ITEM.compareAndSet(this, cmp, val); + /** Returns true if this node has been matched or cancelled */ + final boolean matched() { + return isData != (item != null); } /** - * Links node to itself to avoid garbage retention. Called - * only after CASing head field, so uses relaxed write. + * Relaxed write to replace reference to user data with + * self-link. Can be used only if not already null after + * match. */ - final void selfLink() { - // assert isMatched(); - NEXT.setRelease(this, this); + final void selfLinkItem() { + ITEM.set(this, this); } - final void appendRelaxed(Node next) { - // assert next != null; - // assert this.next == null; - NEXT.setOpaque(this, next); - } + /** The number of times to spin when eligible */ + private static final int SPINS = 1 << 7; /** - * Returns true if this node has been matched, including the - * case of artificial matches due to cancellation. + * The number of nanoseconds for which it is faster to spin + * rather than to use timed park. A rough estimate suffices. */ - final boolean isMatched() { - return isData == (item == null); - } + private static final long SPIN_FOR_TIMEOUT_THRESHOLD = 1L << 10; - /** Tries to CAS-match this node; if successful, wakes waiter. */ - final boolean tryMatch(Object cmp, Object val) { - if (casItem(cmp, val)) { - LockSupport.unpark(waiter); - return true; - } - return false; - } + /** + * True if system is a uniprocessor, occasionally rechecked. + */ + private static boolean isUniprocessor = + (Runtime.getRuntime().availableProcessors() == 1); /** - * Returns true if a node with the given mode cannot be - * appended to this node because this node is unmatched and - * has opposite data mode. + * Refresh rate (probablility) for updating isUniprocessor + * field, to reduce the likeihood that multiple calls to await + * will contend invoking Runtime.availableProcessors. Must be + * a power of two minus one. */ - final boolean cannotPrecede(boolean haveData) { - boolean d = isData; - return d != haveData && d != (item == null); + private static final int UNIPROCESSOR_REFRESH_RATE = (1 << 5) - 1; + + /** + * Possibly blocks until matched or caller gives up. + * + * @param e the comparison value for checking match + * @param ns timeout, or Long.MAX_VALUE if untimed + * @param blocker the LockSupport.setCurrentBlocker argument + * @param spin true if should spin when enabled + * @return matched item, or e if unmatched on interrupt or timeout + */ + final Object await(Object e, long ns, Object blocker, boolean spin) { + Object m; // the match or e if none + boolean timed = (ns != Long.MAX_VALUE); + long deadline = (timed) ? System.nanoTime() + ns : 0L; + boolean upc = isUniprocessor; // don't spin but later recheck + Thread w = Thread.currentThread(); + if (w.isVirtual()) // don't spin + spin = false; + int spins = (spin & !upc) ? SPINS : 0; // negative when may park + while ((m = item) == e) { + if (spins >= 0) { + if (--spins >= 0) + Thread.onSpinWait(); + else { // prepare to park + if (spin) // occasionally recheck + checkForUniprocessor(upc); + LockSupport.setCurrentBlocker(blocker); + waiter = w; // ensure ordering + VarHandle.fullFence(); + } + } else if (w.isInterrupted() || + (timed && // try to cancel with impossible match + ((ns = deadline - System.nanoTime()) <= 0L))) { + m = cmpExItem(e, (e == null) ? this : null); + break; + } else if (timed) { + if (ns < SPIN_FOR_TIMEOUT_THRESHOLD) + Thread.onSpinWait(); + else + LockSupport.parkNanos(ns); + } else if (w instanceof ForkJoinWorkerThread) { + try { + ForkJoinPool.managedBlock(this); + } catch (InterruptedException cannotHappen) { } + } else + LockSupport.park(); + } + if (spins < 0) { + LockSupport.setCurrentBlocker(null); + waiter = null; + } + return m; } - public final boolean isReleasable() { - return (isData == (item == null)) || - Thread.currentThread().isInterrupted(); + /** Occasionally updates isUniprocessor field */ + private void checkForUniprocessor(boolean prev) { + int r = ThreadLocalRandom.nextSecondarySeed(); + if ((r & UNIPROCESSOR_REFRESH_RATE) == 0) { + boolean u = (Runtime.getRuntime().availableProcessors() == 1); + if (u != prev) + isUniprocessor = u; + } } + // ManagedBlocker support + public final boolean isReleasable() { + return (matched() || Thread.currentThread().isInterrupted()); + } public final boolean block() { while (!isReleasable()) LockSupport.park(); return true; } - private static final long serialVersionUID = -3375979862319811754L; + // VarHandle mechanics + static final VarHandle ITEM; + static final VarHandle NEXT; + static { + try { + Class tn = DualNode.class; + MethodHandles.Lookup l = MethodHandles.lookup(); + ITEM = l.findVarHandle(tn, "item", Object.class); + NEXT = l.findVarHandle(tn, "next", tn); + } catch (ReflectiveOperationException e) { + throw new ExceptionInInitializerError(e); + } + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.org/browse/JDK-8074773 + Class ensureLoaded = LockSupport.class; + } } /** - * A node from which the first live (non-matched) node (if any) - * can be reached in O(1) time. + * Unless empty (in which case possibly null), a node from which + * all live nodes are reachable. * Invariants: - * - all live nodes are reachable from head via .next - * - head != null - * - (tmp = head).next != tmp || tmp != head + * - head is never self-linked * Non-invariants: * - head may or may not be live - * - it is permitted for tail to lag behind head, that is, for tail - * to not be reachable from head! + * + * This field is used by subclass SynchronousQueue.Transferer to + * record the top of a Lifo stack, with tail always null, but + * otherwise maintaining the same properties. */ - transient volatile Node head; + transient volatile DualNode head; /** - * A node from which the last node on list (that is, the unique - * node with node.next == null) can be reached in O(1) time. - * Invariants: - * - the last node is always reachable from tail via .next - * - tail != null + * Unless null, a node from which the last node on list (that is, + * the unique node with node.next == null), if one exists, can be + * reached. * Non-invariants: * - tail may or may not be live - * - it is permitted for tail to lag behind head, that is, for tail - * to not be reachable from head! - * - tail.next may or may not be self-linked. + * - tail may be the same as head + * - tail may or may not be self-linked. + * - tail may lag behind head, so need not be reachable from head */ - private transient volatile Node tail; + transient volatile DualNode tail; /** The number of apparent failures to unsplice cancelled nodes */ - private transient volatile boolean needSweep; + transient volatile int sweepVotes; - private boolean casTail(Node cmp, Node val) { - // assert cmp != null; - // assert val != null; - return TAIL.compareAndSet(this, cmp, val); - } + // Atomic updates - private boolean casHead(Node cmp, Node val) { - return HEAD.compareAndSet(this, cmp, val); + final DualNode cmpExTail(DualNode cmp, DualNode val) { + return (DualNode)TAIL.compareAndExchange(this, cmp, val); } - - /** - * Tries to CAS pred.next (or head, if pred is null) from c to p. - * Caller must ensure that we're not unlinking the trailing node. - */ - private boolean tryCasSuccessor(Node pred, Node c, Node p) { - // assert p != null; - // assert c.isData != (c.item != null); - // assert c != p; - if (pred != null) - return pred.casNext(c, p); - if (casHead(c, p)) { - c.selfLink(); - return true; - } - return false; + final DualNode cmpExHead(DualNode cmp, DualNode val) { + return (DualNode)HEAD.compareAndExchange(this, cmp, val); } /** - * Collapses dead (matched) nodes between pred and q. - * @param pred the last known live node, or null if none - * @param c the first dead node - * @param p the last dead node - * @param q p.next: the next live node, or null if at end - * @return pred if pred still alive and CAS succeeded; else p + * The maximum number of estimated removal failures (sweepVotes) + * to tolerate before sweeping through the queue unlinking + * dead nodes that were initially pinned. Must be a power of + * two minus one, at least 3. */ - private Node skipDeadNodes(Node pred, Node c, Node p, Node q) { - // assert pred != c; - // assert p != q; - // assert c.isMatched(); - // assert p.isMatched(); - if (q == null) { - // Never unlink trailing node. - if (c == p) return pred; - q = p; - } - return (tryCasSuccessor(pred, c, q) - && (pred == null || !pred.isMatched())) - ? pred : p; - } + static final int SWEEP_THRESHOLD = (1 << 4) - 1; /** - * Collapses dead (matched) nodes from h (which was once head) to p. - * Caller ensures all nodes from h up to and including p are dead. + * Adds a sweepVote and returns true if triggered threshold. */ - private void skipDeadNodesNearHead(Node h, Node p) { - // assert h != null; - // assert h != p; - // assert p.isMatched(); - for (;;) { - final Node q; - if ((q = p.next) == null) break; - else if (!q.isMatched()) { p = q; break; } - else if (p == (p = q)) return; - } - if (casHead(h, p)) - h.selfLink(); + final boolean sweepNow() { + return (SWEEP_THRESHOLD == + ((int)SWEEPVOTES.getAndAdd(this, 1) & (SWEEP_THRESHOLD))); } - /* Possible values for "how" argument in xfer method. */ - - private static final int NOW = 0; // for untimed poll, tryTransfer - private static final int ASYNC = 1; // for offer, put, add - private static final int SYNC = 2; // for transfer, take - private static final int TIMED = 3; // for timed poll, tryTransfer - /** - * Implements all queuing methods. See above for explanation. + * Implements all queuing methods. Loops, trying: + * + * * If not initialized, try to add new node (unless immediate) and exit + * * If tail has same mode, start traversing at tail for a likely + * append, else at head for a likely match + * * Traverse over dead or wrong-mode nodes until finding a spot + * to match/append, or falling off the list because of self-links. + * * On success, update head or tail if slacked, and possibly wait, + * depending on ns argument * * @param e the item or null for take - * @param haveData true if this is a put, else a take - * @param how NOW, ASYNC, SYNC, or TIMED - * @param nanos timeout in nanosecs, used only if mode is TIMED + * @param ns timeout or negative if async, 0 if immediate, + * Long.MAX_VALUE if untimed * @return an item if matched, else e - * @throws NullPointerException if haveData mode but e is null */ - @SuppressWarnings("unchecked") - private E xfer(E e, boolean haveData, int how, long nanos) { - if (haveData && (e == null)) - throw new NullPointerException(); - - restart: for (Node s = null, t = null, h = null;;) { - for (Node p = (t != (t = tail) && t.isData == haveData) ? t - : (h = head);; ) { - final Node q; final Object item; - if (p.isData != haveData - && haveData == ((item = p.item) == null)) { - if (h == null) h = head; - if (p.tryMatch(item, e)) { - if (h != p) skipDeadNodesNearHead(h, p); - return (E) item; + final Object xfer(Object e, long ns) { + boolean haveData = (e != null); + Object m; // the match or e if none + DualNode s = null, p; // enqueued node and its predecessor + restart: for (DualNode prevp = null;;) { + DualNode h, t, q; + if ((h = head) == null && // initialize unless immediate + (ns == 0L || + (h = cmpExHead(null, s = new DualNode(e, haveData))) == null)) { + p = null; // no predecessor + break; // else lost init race + } + p = (t = tail) != null && t.isData == haveData && t != prevp ? t : h; + prevp = p; // avoid known self-linked tail path + do { + m = p.item; + q = p.next; + if (p.isData != haveData && haveData != (m != null) && + p.cmpExItem(m, e) == m) { + Thread w = p.waiter; // matched complementary node + if (p != h && h == cmpExHead(h, (q == null) ? p : q)) + h.next = h; // advance head; self-link old + LockSupport.unpark(w); + return m; + } else if (q == null) { + if (ns == 0L) // try to append unless immediate + break restart; + if (s == null) + s = new DualNode(e, haveData); + if ((q = p.cmpExNext(null, s)) == null) { + if (p != t) + cmpExTail(t, s); + break restart; } } - if ((q = p.next) == null) { - if (how == NOW) return e; - if (s == null) s = new Node(e); - if (!p.casNext(null, s)) continue; - if (p != t) casTail(t, s); - if (how == ASYNC) return e; - return awaitMatch(s, p, e, (how == TIMED), nanos); - } - if (p == (p = q)) continue restart; - } + } while (p != (p = q)); // restart if self-linked } + if (s == null || ns <= 0L) + m = e; // don't wait + else if ((m = s.await(e, ns, this, // spin if at or near head + p == null || p.waiter == null)) == e) + unsplice(p, s); // cancelled + else if (m != null) + s.selfLinkItem(); + + return m; } + /* -------------- Removals -------------- */ + /** - * Possibly blocks until node s is matched or caller gives up. + * Unlinks (now or later) the given (non-live) node with given + * predecessor. See above for rationale. * - * @param s the waiting node - * @param pred the predecessor of s, or null if unknown (the null - * case does not occur in any current calls but may in possible - * future extensions) - * @param e the comparison value for checking match - * @param timed if true, wait only until timeout elapses - * @param nanos timeout in nanosecs, used only if timed is true - * @return matched item, or e if unmatched on interrupt or timeout + * @param pred if nonnull, a node that was at one time known to be the + * predecessor of s (else s may have been head) + * @param s the node to be unspliced */ - @SuppressWarnings("unchecked") - private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) { - final boolean isData = s.isData; - final long deadline = timed ? System.nanoTime() + nanos : 0L; - final Thread w = Thread.currentThread(); - int stat = -1; // -1: may yield, +1: park, else 0 - Object item; - while ((item = s.item) == e) { - if (needSweep) // help clean - sweep(); - else if ((timed && nanos <= 0L) || w.isInterrupted()) { - if (s.casItem(e, (e == null) ? s : null)) { - unsplice(pred, s); // cancelled - return e; - } - } - else if (stat <= 0) { - if (pred != null && pred.next == s) { - if (stat < 0 && - (pred.isData != isData || pred.isMatched())) { - stat = 0; // yield once if first - Thread.yield(); - } - else { - stat = 1; - s.waiter = w; // enable unpark - } - } // else signal in progress - } - else if ((item = s.item) != e) - break; // recheck - else if (!timed) { - LockSupport.setCurrentBlocker(this); - try { - ForkJoinPool.managedBlock(s); - } catch (InterruptedException cannotHappen) { } - LockSupport.setCurrentBlocker(null); - } + private void unsplice(DualNode pred, DualNode s) { + boolean seen = false; // try removing by collapsing head + for (DualNode h = head, p = h, f; p != null;) { + boolean matched; + if (p == s) + matched = seen = true; + else + matched = p.matched(); + if ((f = p.next) == p) + p = h = head; + else if (f != null && matched) + p = f; else { - nanos = deadline - System.nanoTime(); - if (nanos > SPIN_FOR_TIMEOUT_THRESHOLD) - LockSupport.parkNanos(this, nanos); + if (p != h && cmpExHead(h, p) == h) + h.next = h; // self-link + break; + } + } + DualNode sn; // try to unsplice if not pinned + if (!seen && + pred != null && pred.next == s && s != null && (sn = s.next) != s && + (sn == null || pred.cmpExNext(s, sn) != s || pred.matched()) && + sweepNow()) { // occasionally sweep if might not have been removed + for (DualNode p = head, f, n, u; + p != null && (f = p.next) != null && (n = f.next) != null;) { + p = (f == p ? head : // stale + !f.matched() ? f : // skip + f == (u = p.cmpExNext(f, n)) ? n : u); // unspliced } } - if (stat == 1) - WAITER.set(s, null); - if (!isData) - ITEM.set(s, s); // self-link to avoid garbage - return (E) item; + } + + /** + * Tries to CAS pred.next (or head, if pred is null) from c to p. + * Caller must ensure that we're not unlinking the trailing node. + */ + final boolean tryCasSuccessor(DualNode pred, DualNode c, DualNode p) { + // assert p != null && c.matched() && c != p; + if (pred != null) + return pred.cmpExNext(c, p) == c; + else if (cmpExHead(c, p) != c) + return false; + if (c != null) + c.next = c; + + return true; + } + + /** + * Collapses dead (matched) nodes between pred and q. + * @param pred the last known live node, or null if none + * @param c the first dead node + * @param p the last dead node + * @param q p.next: the next live node, or null if at end + * @return pred if pred still alive and CAS succeeded; else p + */ + final DualNode skipDeadNodes(DualNode pred, DualNode c, + DualNode p, DualNode q) { + // assert pred != c && p != q; && c.matched() && p.matched(); + if (q == null) { // Never unlink trailing node. + if (c == p) + return pred; + q = p; + } + return (tryCasSuccessor(pred, c, q) && (pred == null || !pred.matched())) + ? pred : p; + } + + /** + * Tries to match the given object only if p is a data + * node. Signals waiter on success. + */ + final boolean tryMatchData(DualNode p, Object x) { + if (p != null && p.isData && + x != null && p.cmpExItem(x, null) == x) { + LockSupport.unpark(p.waiter); + return true; + } + return false; } /* -------------- Traversal methods -------------- */ @@ -690,40 +717,39 @@ * Callers must recheck if the returned node is unmatched * before using. */ - final Node firstDataNode() { - Node first = null; - restartFromHead: for (;;) { - Node h = head, p = h; - while (p != null) { - if (p.item != null) { - if (p.isData) { - first = p; - break; - } - } - else if (!p.isData) - break; - final Node q; - if ((q = p.next) == null) - break; - if (p == (p = q)) - continue restartFromHead; + final DualNode firstDataNode() { + for (DualNode h = head, p = h, q, u; p != null;) { + boolean isData = p.isData; + Object item = p.item; + if (isData && item != null) // is live data + return p; + else if (!isData && item == null) // is live request + break; + else if ((q = p.next) == null) // end of list + break; + else if (p == q) // self-link; restart + p = h = head; + else if (p == h) // traverse past header + p = q; + else if ((u = cmpExHead(h, q)) != h) + p = h = u; // lost update race + else { + h.next = h; // collapse; self-link + p = h = q; } - if (p != h && casHead(h, p)) - h.selfLink(); - return first; } + return null; } /** * Traverses and counts unmatched nodes of the given mode. * Used by methods size and getWaitingConsumerCount. */ - private int countOfMode(boolean data) { + final int countOfMode(boolean data) { restartFromHead: for (;;) { int count = 0; - for (Node p = head; p != null;) { - if (!p.isMatched()) { + for (DualNode p = head; p != null;) { + if (!p.matched()) { if (p.isData != data) return 0; if (++count == Integer.MAX_VALUE) @@ -741,7 +767,7 @@ restartFromHead: for (;;) { int charLength = 0; int size = 0; - for (Node p = head; p != null;) { + for (DualNode p = head; p != null;) { Object item = p.item; if (p.isData) { if (item != null) { @@ -770,7 +796,7 @@ Object[] x = a; restartFromHead: for (;;) { int size = 0; - for (Node p = head; p != null;) { + for (DualNode p = head; p != null;) { Object item = p.item; if (p.isData) { if (item != null) { @@ -863,27 +889,28 @@ * but O(n) in the worst case, when lastRet is concurrently deleted. */ final class Itr implements Iterator { - private Node nextNode; // next node to return item for - private E nextItem; // the corresponding item - private Node lastRet; // last returned node, to support remove - private Node ancestor; // Helps unlink lastRet on remove() + private DualNode nextNode; // next node to return item for + private E nextItem; // the corresponding item + private DualNode lastRet; // last returned node, to support remove + private DualNode ancestor; // Helps unlink lastRet on remove() /** * Moves to next node after pred, or first node if pred null. */ @SuppressWarnings("unchecked") - private void advance(Node pred) { - for (Node p = (pred == null) ? head : pred.next, c = p; + private void advance(DualNode pred) { + for (DualNode p = (pred == null) ? head : pred.next, c = p; p != null; ) { - final Object item; - if ((item = p.item) != null && p.isData) { + boolean isData = p.isData; + Object item = p.item; + if (isData && item != null) { nextNode = p; nextItem = (E) item; if (c != p) tryCasSuccessor(pred, c, p); return; } - else if (!p.isData && item == null) + else if (!isData && item == null) break; if (c != p && !tryCasSuccessor(pred, c, c = p)) { pred = p; @@ -907,7 +934,7 @@ } public final E next() { - final Node p; + DualNode p; if ((p = nextNode) == null) throw new NoSuchElementException(); E e = nextItem; advance(lastRet = p); @@ -916,28 +943,26 @@ public void forEachRemaining(Consumer action) { Objects.requireNonNull(action); - Node q = null; - for (Node p; (p = nextNode) != null; advance(q = p)) + DualNode q = null; + for (DualNode p; (p = nextNode) != null; advance(q = p)) action.accept(nextItem); if (q != null) lastRet = q; } public final void remove() { - final Node lastRet = this.lastRet; + final DualNode lastRet = this.lastRet; if (lastRet == null) throw new IllegalStateException(); this.lastRet = null; if (lastRet.item == null) // already deleted? return; // Advance ancestor, collapsing intervening dead nodes - Node pred = ancestor; - for (Node p = (pred == null) ? head : pred.next, c = p, q; + DualNode pred = ancestor; + for (DualNode p = (pred == null) ? head : pred.next, c = p, q; p != null; ) { if (p == lastRet) { - final Object item; - if ((item = p.item) != null) - p.tryMatch(item, null); + tryMatchData(p, p.item); if ((q = p.next) == null) q = p; if (c != q) tryCasSuccessor(pred, c, q); ancestor = pred; @@ -962,20 +987,20 @@ // leave ancestor at original location to avoid overshoot; // better luck next time! - // assert lastRet.isMatched(); + // assert lastRet.matched(); } } /** A customized variant of Spliterators.IteratorSpliterator */ final class LTQSpliterator implements Spliterator { static final int MAX_BATCH = 1 << 25; // max batch array size; - Node current; // current node; null until initialized + DualNode current; // current node; null until initialized int batch; // batch size for splits boolean exhausted; // true when no more nodes LTQSpliterator() {} public Spliterator trySplit() { - Node p, q; + DualNode p, q; if ((p = current()) == null || (q = p.next) == null) return null; int i = 0, n = batch = Math.min(batch + 1, MAX_BATCH); @@ -1004,7 +1029,7 @@ public void forEachRemaining(Consumer action) { Objects.requireNonNull(action); - final Node p; + final DualNode p; if ((p = current()) != null) { current = null; exhausted = true; @@ -1015,12 +1040,12 @@ @SuppressWarnings("unchecked") public boolean tryAdvance(Consumer action) { Objects.requireNonNull(action); - Node p; + DualNode p; if ((p = current()) != null) { E e = null; do { - final Object item = p.item; - final boolean isData = p.isData; + boolean isData = p.isData; + Object item = p.item; if (p == (p = p.next)) p = head; if (isData) { @@ -1041,13 +1066,13 @@ return false; } - private void setCurrent(Node p) { + private void setCurrent(DualNode p) { if ((current = p) == null) exhausted = true; } - private Node current() { - Node p; + private DualNode current() { + DualNode p; if ((p = current) == null && !exhausted) setCurrent(p = firstDataNode()); return p; @@ -1082,76 +1107,10 @@ return new LTQSpliterator(); } - /* -------------- Removal methods -------------- */ - - /** - * Unsplices (now or later) the given deleted/cancelled node with - * the given predecessor. - * - * @param pred a node that was at one time known to be the - * predecessor of s - * @param s the node to be unspliced - */ - final void unsplice(Node pred, Node s) { - // assert pred != null; - // assert pred != s; - // assert s != null; - // assert s.isMatched(); - // assert (SWEEP_THRESHOLD & (SWEEP_THRESHOLD - 1)) == 0; - s.waiter = null; // disable signals - /* - * See above for rationale. Briefly: if pred still points to - * s, try to unlink s. If s cannot be unlinked, because it is - * trailing node or pred might be unlinked, and neither pred - * nor s are head or offlist, set needSweep; - */ - if (pred != null && pred.next == s) { - Node n = s.next; - if (n == null || - (n != s && pred.casNext(s, n) && pred.isMatched())) { - for (;;) { // check if at, or could be, head - Node h = head; - if (h == pred || h == s) - return; // at head or list empty - if (!h.isMatched()) - break; - Node hn = h.next; - if (hn == null) - return; // now empty - if (hn != h && casHead(h, hn)) - h.selfLink(); // advance head - } - if (pred.next != pred && s.next != s) - needSweep = true; - } - } - } - - /** - * Unlinks matched (typically cancelled) nodes encountered in a - * traversal from head. - */ - private void sweep() { - needSweep = false; - for (Node p = head, s, n; p != null && (s = p.next) != null; ) { - if (!s.isMatched()) - // Unmatched nodes are never self-linked - p = s; - else if ((n = s.next) == null) // trailing node is pinned - break; - else if (s == n) // stale - // No need to also check for p == s, since that implies s == n - p = head; - else - p.casNext(s, n); - } - } - /** * Creates an initially empty {@code LinkedTransferQueue}. */ public LinkedTransferQueue() { - head = tail = new Node(); } /** @@ -1164,16 +1123,15 @@ * of its elements are null */ public LinkedTransferQueue(Collection c) { - Node h = null, t = null; + DualNode h = null, t = null; for (E e : c) { - Node newNode = new Node(Objects.requireNonNull(e)); - if (h == null) - h = t = newNode; + DualNode newNode = new DualNode(Objects.requireNonNull(e), true); + if (t == null) + h = newNode; else - t.appendRelaxed(t = newNode); + t.next = newNode; + t = newNode; } - if (h == null) - h = t = new Node(); head = h; tail = t; } @@ -1185,7 +1143,7 @@ * @throws NullPointerException if the specified element is null */ public void put(E e) { - xfer(e, true, ASYNC, 0L); + offer(e); } /** @@ -1198,8 +1156,7 @@ * @throws NullPointerException if the specified element is null */ public boolean offer(E e, long timeout, TimeUnit unit) { - xfer(e, true, ASYNC, 0L); - return true; + return offer(e); } /** @@ -1210,7 +1167,8 @@ * @throws NullPointerException if the specified element is null */ public boolean offer(E e) { - xfer(e, true, ASYNC, 0L); + Objects.requireNonNull(e); + xfer(e, -1L); return true; } @@ -1223,8 +1181,7 @@ * @throws NullPointerException if the specified element is null */ public boolean add(E e) { - xfer(e, true, ASYNC, 0L); - return true; + return offer(e); } /** @@ -1238,7 +1195,8 @@ * @throws NullPointerException if the specified element is null */ public boolean tryTransfer(E e) { - return xfer(e, true, NOW, 0L) == null; + Objects.requireNonNull(e); + return xfer(e, 0L) == null; } /** @@ -1253,10 +1211,13 @@ * @throws NullPointerException if the specified element is null */ public void transfer(E e) throws InterruptedException { - if (xfer(e, true, SYNC, 0L) != null) { + Objects.requireNonNull(e); + if (!Thread.interrupted()) { + if (xfer(e, Long.MAX_VALUE) == null) + return; Thread.interrupted(); // failure possible only due to interrupt - throw new InterruptedException(); } + throw new InterruptedException(); } /** @@ -1275,30 +1236,38 @@ */ public boolean tryTransfer(E e, long timeout, TimeUnit unit) throws InterruptedException { - if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null) + Objects.requireNonNull(e); + long nanos = Math.max(unit.toNanos(timeout), 0L); + if (xfer(e, nanos) == null) return true; if (!Thread.interrupted()) return false; throw new InterruptedException(); } + @SuppressWarnings("unchecked") public E take() throws InterruptedException { - E e = xfer(null, false, SYNC, 0L); - if (e != null) - return e; - Thread.interrupted(); + Object e; + if (!Thread.interrupted()) { + if ((e = xfer(null, Long.MAX_VALUE)) != null) + return (E) e; + Thread.interrupted(); + } throw new InterruptedException(); } + @SuppressWarnings("unchecked") public E poll(long timeout, TimeUnit unit) throws InterruptedException { - E e = xfer(null, false, TIMED, unit.toNanos(timeout)); - if (e != null || !Thread.interrupted()) - return e; + Object e; + long nanos = Math.max(unit.toNanos(timeout), 0L); + if ((e = xfer(null, nanos)) != null || !Thread.interrupted()) + return (E) e; throw new InterruptedException(); } + @SuppressWarnings("unchecked") public E poll() { - return xfer(null, false, NOW, 0L); + return (E) xfer(null, 0L); } /** @@ -1344,7 +1313,7 @@ public E peek() { restartFromHead: for (;;) { - for (Node p = head; p != null;) { + for (DualNode p = head; p != null;) { Object item = p.item; if (p.isData) { if (item != null) { @@ -1372,7 +1341,7 @@ public boolean hasWaitingConsumer() { restartFromHead: for (;;) { - for (Node p = head; p != null;) { + for (DualNode p = head; p != null;) { Object item = p.item; if (p.isData) { if (item != null) @@ -1421,22 +1390,23 @@ public boolean remove(Object o) { if (o == null) return false; restartFromHead: for (;;) { - for (Node p = head, pred = null; p != null; ) { - Node q = p.next; - final Object item; - if ((item = p.item) != null) { - if (p.isData) { - if (o.equals(item) && p.tryMatch(item, null)) { + for (DualNode p = head, pred = null; p != null; ) { + boolean isData = p.isData; + Object item = p.item; + DualNode q = p.next; + if (item != null) { + if (isData) { + if (o.equals(item) && tryMatchData(p, item)) { skipDeadNodes(pred, p, p, q); return true; } pred = p; p = q; continue; } } - else if (!p.isData) + else if (!isData) break; - for (Node c = p;; q = p.next) { - if (q == null || !q.isMatched()) { + for (DualNode c = p;; q = p.next) { + if (q == null || !q.matched()) { pred = skipDeadNodes(pred, c, p, q); p = q; break; } if (p == (p = q)) continue restartFromHead; @@ -1457,20 +1427,21 @@ public boolean contains(Object o) { if (o == null) return false; restartFromHead: for (;;) { - for (Node p = head, pred = null; p != null; ) { - Node q = p.next; - final Object item; - if ((item = p.item) != null) { - if (p.isData) { + for (DualNode p = head, pred = null; p != null; ) { + boolean isData = p.isData; + Object item = p.item; + DualNode q = p.next; + if (item != null) { + if (isData) { if (o.equals(item)) return true; pred = p; p = q; continue; } } - else if (!p.isData) + else if (!isData) break; - for (Node c = p;; q = p.next) { - if (q == null || !q.isMatched()) { + for (DualNode c = p;; q = p.next) { + if (q == null || !q.matched()) { pred = skipDeadNodes(pred, c, p, q); p = q; break; } if (p == (p = q)) continue restartFromHead; @@ -1519,16 +1490,15 @@ throws java.io.IOException, ClassNotFoundException { // Read in elements until trailing null sentinel found - Node h = null, t = null; + DualNode h = null, t = null; for (Object item; (item = s.readObject()) != null; ) { - Node newNode = new Node(item); - if (h == null) - h = t = newNode; + DualNode newNode = new DualNode(item, true); + if (t == null) + h = newNode; else - t.appendRelaxed(t = newNode); + t.next = newNode; + t = newNode; } - if (h == null) - h = t = new Node(); head = h; tail = t; } @@ -1567,6 +1537,7 @@ */ private static final int MAX_HOPS = 8; + /** Implementation of bulk remove methods. */ @SuppressWarnings("unchecked") private boolean bulkRemove(Predicate filter) { @@ -1575,24 +1546,24 @@ int hops = MAX_HOPS; // c will be CASed to collapse intervening dead nodes between // pred (or head if null) and p. - for (Node p = head, c = p, pred = null, q; p != null; p = q) { + for (DualNode p = head, c = p, pred = null, q; p != null; p = q) { + boolean isData = p.isData, pAlive; + Object item = p.item; q = p.next; - final Object item; boolean pAlive; - if (pAlive = ((item = p.item) != null && p.isData)) { + if (pAlive = (item != null && isData)) { if (filter.test((E) item)) { - if (p.tryMatch(item, null)) + if (tryMatchData(p, item)) removed = true; pAlive = false; } } - else if (!p.isData && item == null) + else if (!isData && item == null) break; if (pAlive || q == null || --hops == 0) { // p might already be self-linked here, but if so: // - CASing head will surely fail // - CASing pred's next will be useless but harmless. - if ((c != p && !tryCasSuccessor(pred, c, c = p)) - || pAlive) { + if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) { // if CAS failed or alive, abandon old pred hops = MAX_HOPS; pred = p; @@ -1610,20 +1581,21 @@ * If p is null, the action is not run. */ @SuppressWarnings("unchecked") - void forEachFrom(Consumer action, Node p) { - for (Node pred = null; p != null; ) { - Node q = p.next; - final Object item; - if ((item = p.item) != null) { - if (p.isData) { + void forEachFrom(Consumer action, DualNode p) { + for (DualNode pred = null; p != null; ) { + boolean isData = p.isData; + Object item = p.item; + DualNode q = p.next; + if (item != null) { + if (isData) { action.accept((E) item); pred = p; p = q; continue; } } - else if (!p.isData) + else if (!isData) break; - for (Node c = p;; q = p.next) { - if (q == null || !q.isMatched()) { + for (DualNode c = p;; q = p.next) { + if (q == null || !q.matched()) { pred = skipDeadNodes(pred, c, p, q); p = q; break; } if (p == (p = q)) { pred = null; p = head; break; } @@ -1640,27 +1612,18 @@ } // VarHandle mechanics - private static final VarHandle HEAD; - private static final VarHandle TAIL; - static final VarHandle ITEM; - static final VarHandle NEXT; - static final VarHandle WAITER; + static final VarHandle HEAD; + static final VarHandle TAIL; + static final VarHandle SWEEPVOTES; static { try { + Class ltq = LinkedTransferQueue.class, tn = DualNode.class; MethodHandles.Lookup l = MethodHandles.lookup(); - HEAD = l.findVarHandle(LinkedTransferQueue.class, "head", - Node.class); - TAIL = l.findVarHandle(LinkedTransferQueue.class, "tail", - Node.class); - ITEM = l.findVarHandle(Node.class, "item", Object.class); - NEXT = l.findVarHandle(Node.class, "next", Node.class); - WAITER = l.findVarHandle(Node.class, "waiter", Thread.class); + HEAD = l.findVarHandle(ltq, "head", tn); + TAIL = l.findVarHandle(ltq, "tail", tn); + SWEEPVOTES = l.findVarHandle(ltq, "sweepVotes", int.class); } catch (ReflectiveOperationException e) { throw new ExceptionInInitializerError(e); } - - // Reduce the risk of rare disastrous classloading in first call to - // LockSupport.park: https://bugs.openjdk.org/browse/JDK-8074773 - Class ensureLoaded = LockSupport.class; } } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java openjdk-21-21.0.2+13/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java 2024-01-16 16:19:00.000000000 +0000 @@ -47,6 +47,9 @@ import java.util.Spliterators; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.TransferQueue; /** * A {@linkplain BlockingQueue blocking queue} in which each insert @@ -98,717 +101,137 @@ * M. L. Scott. 18th Annual Conf. on Distributed Computing, * Oct. 2004 (see also * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/duals.html). - * The (Lifo) stack is used for non-fair mode, and the (Fifo) - * queue for fair mode. The performance of the two is generally - * similar. Fifo usually supports higher throughput under - * contention but Lifo maintains higher thread locality in common - * applications. - * - * A dual queue (and similarly stack) is one that at any given - * time either holds "data" -- items provided by put operations, - * or "requests" -- slots representing take operations, or is - * empty. A call to "fulfill" (i.e., a call requesting an item - * from a queue holding data or vice versa) dequeues a - * complementary node. The most interesting feature of these - * queues is that any operation can figure out which mode the - * queue is in, and act accordingly without needing locks. - * - * Both the queue and stack extend abstract class Transferer - * defining the single method transfer that does a put or a - * take. These are unified into a single method because in dual - * data structures, the put and take operations are symmetrical, - * so nearly all code can be combined. The resulting transfer - * methods are on the long side, but are easier to follow than - * they would be if broken up into nearly-duplicated parts. - * - * The queue and stack data structures share many conceptual - * similarities but very few concrete details. For simplicity, - * they are kept distinct so that they can later evolve - * separately. + * The queue is treated as a Lifo stack in non-fair mode, and a + * Fifo queue in fair mode. In most contexts, transfer performance + * is roughly comparable across them. Lifo is usually faster under + * low contention, but slower under high contention. Performance + * of applications using them also varies. Lifo is generally + * preferable in resource management settings (for example cached + * thread pools) because of better temporal locality, but + * inappropriate for message-passing applications. + * + * A dual queue is one that at any given time either holds "data" + * -- items provided by put operations, or "requests" -- slots + * representing take operations, or is empty. A fulfilling + * operation (i.e., a call requesting an item from a queue holding + * data or vice versa) "matches" the item of and then dequeues a + * complementary node. Any operation can figure out which mode + * the queue is in, and act accordingly without needing locks. So + * put and take operations are symmetrical, and all transfer + * methods invoke a single "xfer" method that does a put or a take + * in either fifo or lifo mode. * * The algorithms here differ from the versions in the above paper - * in extending them for use in synchronous queues, as well as - * dealing with cancellation. The main differences include: + * in ways including: * - * 1. The original algorithms used bit-marked pointers, but - * the ones here use mode bits in nodes, leading to a number - * of further adaptations. - * 2. SynchronousQueues must block threads waiting to become - * fulfilled. - * 3. Support for cancellation via timeout and interrupts, - * including cleaning out cancelled nodes/threads - * from lists to avoid garbage retention and memory depletion. - * - * Blocking is mainly accomplished using LockSupport park/unpark, - * except that nodes that appear to be the next ones to become - * fulfilled first spin a bit (on multiprocessors only). On very - * busy synchronous queues, spinning can dramatically improve - * throughput. And on less busy ones, the amount of spinning is - * small enough not to be noticeable. - * - * Cleaning is done in different ways in queues vs stacks. For - * queues, we can almost always remove a node immediately in O(1) - * time (modulo retries for consistency checks) when it is - * cancelled. But if it may be pinned as the current tail, it must - * wait until some subsequent cancellation. For stacks, we need a - * potentially O(n) traversal to be sure that we can remove the - * node, but this can run concurrently with other threads - * accessing the stack. - * - * While garbage collection takes care of most node reclamation - * issues that otherwise complicate nonblocking algorithms, care - * is taken to "forget" references to data, other nodes, and - * threads that might be held on to long-term by blocked - * threads. In cases where setting to null would otherwise - * conflict with main algorithms, this is done by changing a - * node's link to now point to the node itself. This doesn't arise - * much for Stack nodes (because blocked threads do not hang on to - * old head pointers), but references in Queue nodes must be - * aggressively forgotten to avoid reachability of everything any - * node has ever referred to since arrival. - * - * The above steps improve throughput when many threads produce - * and/or consume data. But they don't help much with - * single-source / single-sink usages in which one side or the - * other is always transiently blocked, and so throughput is - * mainly a function of thread scheduling. This is not usually - * noticeably improved with bounded short spin-waits. Instead both - * forms of transfer try Thread.yield if apparently the sole - * waiter. This works well when there are more tasks that cores, - * which is expected to be the main usage context of this mode. In - * other cases, waiters may help with some bookkeeping, then - * park/unpark. + * * The original algorithms used bit-marked pointers, but the + * ones here use a bit (isData) in nodes, and usually avoid + * creating nodes when fulfilling. They also use the + * compareAndExchange form of CAS for pointer updates to + * reduce memory traffic. + * * Fifo mode is based on LinkedTransferQueue operations, but + * Lifo mode support is added in subclass Transferer. + * * The Fifo version accommodates lazy updates and slack as + * described in LinkedTransferQueue internal documentation. + * * Threads may block when waiting to become fulfilled, + * sometimes preceded by brief spins. + * * Support for cancellation via timeout and interrupts, + * including cleaning out cancelled nodes/threads from lists + * to avoid garbage retention and memory depletion. */ /** - * Shared internal API for dual stacks and queues. + * Extension of LinkedTransferQueue to support Lifo (stack) mode. + * Methods use the "head" field as head (top) of stack (versus + * queue). Note that popped nodes are not self-linked because they + * are not prone to unbounded garbage chains. Also note that + * "async" mode is never used and not supported for synchronous + * transfers. */ - abstract static class Transferer { - /** - * Performs a put or take. - * - * @param e if non-null, the item to be handed to a consumer; - * if null, requests that transfer return an item - * offered by producer. - * @param timed if this operation should timeout - * @param nanos the timeout, in nanoseconds - * @return if non-null, the item provided or received; if null, - * the operation failed due to timeout or interrupt -- - * the caller can distinguish which of these occurred - * by checking Thread.interrupted. - */ - abstract E transfer(E e, boolean timed, long nanos); - } - - /** - * The number of nanoseconds for which it is faster to spin - * rather than to use timed park. A rough estimate suffices. - */ - static final long SPIN_FOR_TIMEOUT_THRESHOLD = 1023L; - - /** Dual stack */ - static final class TransferStack extends Transferer { - /* - * This extends Scherer-Scott dual stack algorithm, differing, - * among other ways, by using "covering" nodes rather than - * bit-marked pointers: Fulfilling operations push on marker - * nodes (with FULFILLING bit set in mode) to reserve a spot - * to match a waiting node. - */ - - /* Modes for SNodes, ORed together in node fields */ - /** Node represents an unfulfilled consumer */ - static final int REQUEST = 0; - /** Node represents an unfulfilled producer */ - static final int DATA = 1; - /** Node is fulfilling another unfulfilled DATA or REQUEST */ - static final int FULFILLING = 2; - - /** Returns true if m has fulfilling bit set. */ - static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; } - - /** Node class for TransferStacks. */ - static final class SNode implements ForkJoinPool.ManagedBlocker { - volatile SNode next; // next node in stack - volatile SNode match; // the node matched to this - volatile Thread waiter; // to control park/unpark - Object item; // data; or null for REQUESTs - int mode; - // Note: item and mode fields don't need to be volatile - // since they are always written before, and read after, - // other volatile/atomic operations. - - SNode(Object item) { - this.item = item; - } - - boolean casNext(SNode cmp, SNode val) { - return cmp == next && - SNEXT.compareAndSet(this, cmp, val); - } - - /** - * Tries to match node s to this node, if so, waking up thread. - * Fulfillers call tryMatch to identify their waiters. - * Waiters block until they have been matched. - * - * @param s the node to match - * @return true if successfully matched to s - */ - boolean tryMatch(SNode s) { - SNode m; Thread w; - if ((m = match) == null) { - if (SMATCH.compareAndSet(this, null, s)) { - if ((w = waiter) != null) - LockSupport.unpark(w); - return true; - } - else - m = match; - } - return m == s; - } - - /** - * Tries to cancel a wait by matching node to itself. - */ - boolean tryCancel() { - return SMATCH.compareAndSet(this, null, this); - } - - boolean isCancelled() { - return match == this; - } - - public final boolean isReleasable() { - return match != null || Thread.currentThread().isInterrupted(); - } - - public final boolean block() { - while (!isReleasable()) LockSupport.park(); - return true; - } - - void forgetWaiter() { - SWAITER.setOpaque(this, null); - } - - // VarHandle mechanics - private static final VarHandle SMATCH; - private static final VarHandle SNEXT; - private static final VarHandle SWAITER; - static { - try { - MethodHandles.Lookup l = MethodHandles.lookup(); - SMATCH = l.findVarHandle(SNode.class, "match", SNode.class); - SNEXT = l.findVarHandle(SNode.class, "next", SNode.class); - SWAITER = l.findVarHandle(SNode.class, "waiter", Thread.class); - } catch (ReflectiveOperationException e) { - throw new ExceptionInInitializerError(e); - } - } - } - - /** The head (top) of the stack */ - volatile SNode head; - - boolean casHead(SNode h, SNode nh) { - return h == head && - SHEAD.compareAndSet(this, h, nh); - } + @SuppressWarnings("serial") // never serialized + static final class Transferer extends LinkedTransferQueue { /** - * Creates or resets fields of a node. Called only from transfer - * where the node to push on stack is lazily created and - * reused when possible to help reduce intervals between reads - * and CASes of head and to avoid surges of garbage when CASes - * to push nodes fail due to contention. - */ - static SNode snode(SNode s, Object e, SNode next, int mode) { - if (s == null) s = new SNode(e); - s.mode = mode; - s.next = next; - return s; - } - - /** - * Puts or takes an item. - */ - @SuppressWarnings("unchecked") - E transfer(E e, boolean timed, long nanos) { - /* - * Basic algorithm is to loop trying one of three actions: - * - * 1. If apparently empty or already containing nodes of same - * mode, try to push node on stack and wait for a match, - * returning it, or null if cancelled. - * - * 2. If apparently containing node of complementary mode, - * try to push a fulfilling node on to stack, match - * with corresponding waiting node, pop both from - * stack, and return matched item. The matching or - * unlinking might not actually be necessary because of - * other threads performing action 3: - * - * 3. If top of stack already holds another fulfilling node, - * help it out by doing its match and/or pop - * operations, and then continue. The code for helping - * is essentially the same as for fulfilling, except - * that it doesn't return the item. - */ - - SNode s = null; // constructed/reused as needed - int mode = (e == null) ? REQUEST : DATA; - - for (;;) { - SNode h = head; - if (h == null || h.mode == mode) { // empty or same-mode - if (timed && nanos <= 0L) { // can't wait - if (h != null && h.isCancelled()) - casHead(h, h.next); // pop cancelled node - else - return null; - } else if (casHead(h, s = snode(s, e, h, mode))) { - long deadline = timed ? System.nanoTime() + nanos : 0L; - Thread w = Thread.currentThread(); - int stat = -1; // -1: may yield, +1: park, else 0 - SNode m; // await fulfill or cancel - while ((m = s.match) == null) { - if ((timed && - (nanos = deadline - System.nanoTime()) <= 0) || - w.isInterrupted()) { - if (s.tryCancel()) { - clean(s); // wait cancelled - return null; - } - } else if ((m = s.match) != null) { - break; // recheck - } else if (stat <= 0) { - if (stat < 0 && h == null && head == s) { - stat = 0; // yield once if was empty - Thread.yield(); - } else { - stat = 1; - s.waiter = w; // enable signal - } - } else if (!timed) { - LockSupport.setCurrentBlocker(this); - try { - ForkJoinPool.managedBlock(s); - } catch (InterruptedException cannotHappen) { } - LockSupport.setCurrentBlocker(null); - } else if (nanos > SPIN_FOR_TIMEOUT_THRESHOLD) - LockSupport.parkNanos(this, nanos); - } - if (stat == 1) - s.forgetWaiter(); - Object result = (mode == REQUEST) ? m.item : s.item; - if (h != null && h.next == s) - casHead(h, s.next); // help fulfiller - return (E) result; - } - } else if (!isFulfilling(h.mode)) { // try to fulfill - if (h.isCancelled()) // already cancelled - casHead(h, h.next); // pop and retry - else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) { - for (;;) { // loop until matched or waiters disappear - SNode m = s.next; // m is s's match - if (m == null) { // all waiters are gone - casHead(s, null); // pop fulfill node - s = null; // use new node next time - break; // restart main loop - } - SNode mn = m.next; - if (m.tryMatch(s)) { - casHead(s, mn); // pop both s and m - return (E) ((mode == REQUEST) ? m.item : s.item); - } else // lost match - s.casNext(m, mn); // help unlink - } - } - } else { // help a fulfiller - SNode m = h.next; // m is h's match - if (m == null) // waiter is gone - casHead(h, null); // pop fulfilling node - else { - SNode mn = m.next; - if (m.tryMatch(h)) // help match - casHead(h, mn); // pop both h and m - else // lost match - h.casNext(m, mn); // help unlink + * Puts or takes an item with lifo ordering. Loops trying: + * * If top (var p) exists and is already matched, pop and continue + * * If top has complementary type, try to fulfill by CASing item, + * On success pop (which will succeed unless already helped), + * otherwise restart. + * * If no possible match, unless immediate mode, push a + * node and wait, later unsplicing if cancelled. + * + * @param e the item or null for take + * @param ns timeout or 0 if immediate, Long.MAX_VALUE if untimed + * @return an item if matched, else e + */ + final Object xferLifo(Object e, long ns) { + boolean haveData = (e != null); + Object m; // the match or e if none + outer: for (DualNode s = null, p = head;;) { + while (p != null) { + boolean isData; DualNode n, u; // help collapse + if ((isData = p.isData) != ((m = p.item) != null)) + p = (p == (u = cmpExHead(p, (n = p.next)))) ? n : u; + else if (isData == haveData) // same mode; push below + break; + else if (p.cmpExItem(m, e) != m) + p = head; // missed; restart + else { // matched complementary node + Thread w = p.waiter; + cmpExHead(p, p.next); + LockSupport.unpark(w); + break outer; } } - } - } - - /** - * Unlinks s from the stack. - */ - void clean(SNode s) { - s.item = null; // forget item - s.forgetWaiter(); - - /* - * At worst we may need to traverse entire stack to unlink - * s. If there are multiple concurrent calls to clean, we - * might not see s if another thread has already removed - * it. But we can stop when we see any node known to - * follow s. We use s.next unless it too is cancelled, in - * which case we try the node one past. We don't check any - * further because we don't want to doubly traverse just to - * find sentinel. - */ - - SNode past = s.next; - if (past != null && past.isCancelled()) - past = past.next; - - // Absorb cancelled nodes at head - SNode p; - while ((p = head) != null && p != past && p.isCancelled()) - casHead(p, p.next); - - // Unsplice embedded nodes - while (p != null && p != past) { - SNode n = p.next; - if (n != null && n.isCancelled()) - p.casNext(n, n.next); - else - p = n; - } - } - - // VarHandle mechanics - private static final VarHandle SHEAD; - static { - try { - MethodHandles.Lookup l = MethodHandles.lookup(); - SHEAD = l.findVarHandle(TransferStack.class, "head", SNode.class); - } catch (ReflectiveOperationException e) { - throw new ExceptionInInitializerError(e); - } - } - } - - /** Dual Queue */ - static final class TransferQueue extends Transferer { - /* - * This extends Scherer-Scott dual queue algorithm, differing, - * among other ways, by using modes within nodes rather than - * marked pointers. The algorithm is a little simpler than - * that for stacks because fulfillers do not need explicit - * nodes, and matching is done by CAS'ing QNode.item field - * from non-null to null (for put) or vice versa (for take). - */ - - /** Node class for TransferQueue. */ - static final class QNode implements ForkJoinPool.ManagedBlocker { - volatile QNode next; // next node in queue - volatile Object item; // CAS'ed to or from null - volatile Thread waiter; // to control park/unpark - final boolean isData; - - QNode(Object item, boolean isData) { - this.item = item; - this.isData = isData; - } - - boolean casNext(QNode cmp, QNode val) { - return next == cmp && - QNEXT.compareAndSet(this, cmp, val); - } - - boolean casItem(Object cmp, Object val) { - return item == cmp && - QITEM.compareAndSet(this, cmp, val); - } - - /** - * Tries to cancel by CAS'ing ref to this as item. - */ - boolean tryCancel(Object cmp) { - return QITEM.compareAndSet(this, cmp, this); - } - - boolean isCancelled() { - return item == this; - } - - /** - * Returns true if this node is known to be off the queue - * because its next pointer has been forgotten due to - * an advanceHead operation. - */ - boolean isOffList() { - return next == this; - } - - void forgetWaiter() { - QWAITER.setOpaque(this, null); - } - - boolean isFulfilled() { - Object x; - return isData == ((x = item) == null) || x == this; - } - - public final boolean isReleasable() { - Object x; - return isData == ((x = item) == null) || x == this || - Thread.currentThread().isInterrupted(); - } - - public final boolean block() { - while (!isReleasable()) LockSupport.park(); - return true; - } - - // VarHandle mechanics - private static final VarHandle QITEM; - private static final VarHandle QNEXT; - private static final VarHandle QWAITER; - static { - try { - MethodHandles.Lookup l = MethodHandles.lookup(); - QITEM = l.findVarHandle(QNode.class, "item", Object.class); - QNEXT = l.findVarHandle(QNode.class, "next", QNode.class); - QWAITER = l.findVarHandle(QNode.class, "waiter", Thread.class); - } catch (ReflectiveOperationException e) { - throw new ExceptionInInitializerError(e); + if (ns == 0L) { // no match, no wait + m = e; + break; } - } - } - - /** Head of queue */ - transient volatile QNode head; - /** Tail of queue */ - transient volatile QNode tail; - /** - * Reference to a cancelled node that might not yet have been - * unlinked from queue because it was the last inserted node - * when it was cancelled. - */ - transient volatile QNode cleanMe; - - TransferQueue() { - QNode h = new QNode(null, false); // initialize to dummy node. - head = h; - tail = h; - } - - /** - * Tries to cas nh as new head; if successful, unlink - * old head's next node to avoid garbage retention. - */ - void advanceHead(QNode h, QNode nh) { - if (h == head && - QHEAD.compareAndSet(this, h, nh)) - h.next = h; // forget old next - } - - /** - * Tries to cas nt as new tail. - */ - void advanceTail(QNode t, QNode nt) { - if (tail == t) - QTAIL.compareAndSet(this, t, nt); - } - - /** - * Tries to CAS cleanMe slot. - */ - boolean casCleanMe(QNode cmp, QNode val) { - return cleanMe == cmp && - QCLEANME.compareAndSet(this, cmp, val); - } - - /** - * Puts or takes an item. - */ - @SuppressWarnings("unchecked") - E transfer(E e, boolean timed, long nanos) { - /* Basic algorithm is to loop trying to take either of - * two actions: - * - * 1. If queue apparently empty or holding same-mode nodes, - * try to add node to queue of waiters, wait to be - * fulfilled (or cancelled) and return matching item. - * - * 2. If queue apparently contains waiting items, and this - * call is of complementary mode, try to fulfill by CAS'ing - * item field of waiting node and dequeuing it, and then - * returning matching item. - * - * In each case, along the way, check for and try to help - * advance head and tail on behalf of other stalled/slow - * threads. - * - * The loop starts off with a null check guarding against - * seeing uninitialized head or tail values. This never - * happens in current SynchronousQueue, but could if - * callers held non-volatile/final ref to the - * transferer. The check is here anyway because it places - * null checks at top of loop, which is usually faster - * than having them implicitly interspersed. - */ - - QNode s = null; // constructed/reused as needed - boolean isData = (e != null); - for (;;) { - QNode t = tail, h = head, m, tn; // m is node to fulfill - if (t == null || h == null) - ; // inconsistent - else if (h == t || t.isData == isData) { // empty or same-mode - if (t != tail) // inconsistent - ; - else if ((tn = t.next) != null) // lagging tail - advanceTail(t, tn); - else if (timed && nanos <= 0L) // can't wait - return null; - else if (t.casNext(null, (s != null) ? s : - (s = new QNode(e, isData)))) { - advanceTail(t, s); - long deadline = timed ? System.nanoTime() + nanos : 0L; - Thread w = Thread.currentThread(); - int stat = -1; // same idea as TransferStack - Object item; - while ((item = s.item) == e) { - if ((timed && - (nanos = deadline - System.nanoTime()) <= 0) || - w.isInterrupted()) { - if (s.tryCancel(e)) { - clean(t, s); - return null; - } - } else if ((item = s.item) != e) { - break; // recheck - } else if (stat <= 0) { - if (t.next == s) { - if (stat < 0 && t.isFulfilled()) { - stat = 0; // yield once if first - Thread.yield(); - } - else { - stat = 1; - s.waiter = w; - } - } - } else if (!timed) { - LockSupport.setCurrentBlocker(this); - try { - ForkJoinPool.managedBlock(s); - } catch (InterruptedException cannotHappen) { } - LockSupport.setCurrentBlocker(null); - } - else if (nanos > SPIN_FOR_TIMEOUT_THRESHOLD) - LockSupport.parkNanos(this, nanos); - } - if (stat == 1) - s.forgetWaiter(); - if (!s.isOffList()) { // not already unlinked - advanceHead(t, s); // unlink if head - if (item != null) // and forget fields - s.item = s; - } - return (item != null) ? (E)item : e; - } - - } else if ((m = h.next) != null && t == tail && h == head) { - Thread waiter; - Object x = m.item; - boolean fulfilled = ((isData == (x == null)) && - x != m && m.casItem(x, e)); - advanceHead(h, m); // (help) dequeue - if (fulfilled) { - if ((waiter = m.waiter) != null) - LockSupport.unpark(waiter); - return (x != null) ? (E)x : e; - } + if (s == null) // try to push node and wait + s = new DualNode(e, haveData); + s.next = p; + if (p == (p = cmpExHead(p, s))) { + if ((m = s.await(e, ns, this, // spin if (nearly) empty + p == null || p.waiter == null)) == e) + unspliceLifo(s); // cancelled + break; } } + return m; } /** - * Gets rid of cancelled node s with original predecessor pred. + * Unlinks node s. Same idea as Fifo version. */ - void clean(QNode pred, QNode s) { - s.forgetWaiter(); - /* - * At any given time, exactly one node on list cannot be - * deleted -- the last inserted node. To accommodate this, - * if we cannot delete s, we save its predecessor as - * "cleanMe", deleting the previously saved version - * first. At least one of node s or the node previously - * saved can always be deleted, so this always terminates. - */ - while (pred.next == s) { // Return early if already unlinked - QNode h = head; - QNode hn = h.next; // Absorb cancelled first node as head - if (hn != null && hn.isCancelled()) { - advanceHead(h, hn); - continue; - } - QNode t = tail; // Ensure consistent read for tail - if (t == h) - return; - QNode tn = t.next; - if (t != tail) - continue; - if (tn != null) { - advanceTail(t, tn); - continue; - } - if (s != t) { // If not tail, try to unsplice - QNode sn = s.next; - if (sn == s || pred.casNext(s, sn)) - return; + private void unspliceLifo(DualNode s) { + boolean seen = false; // try removing by collapsing head + DualNode p = head; + for (DualNode f, u; p != null && p.matched();) { + if (p == s) + seen = true; + p = (p == (u = cmpExHead(p, (f = p.next)))) ? f : u; + } + if (p != null && !seen && sweepNow()) { // occasionally sweep + for (DualNode f, n, u; p != null && (f = p.next) != null; ) { + p = (!f.matched() ? f : + f == (u = p.cmpExNext(f, n = f.next)) ? n : u); } - QNode dp = cleanMe; - if (dp != null) { // Try unlinking previous cancelled node - QNode d = dp.next; - QNode dn; - if (d == null || // d is gone or - d == dp || // d is off list or - !d.isCancelled() || // d not cancelled or - (d != t && // d not tail and - (dn = d.next) != null && // has successor - dn != d && // that is on list - dp.casNext(d, dn))) // d unspliced - casCleanMe(dp, null); - if (dp == pred) - return; // s is already saved node - } else if (casCleanMe(null, pred)) - return; // Postpone cleaning s - } - } - - // VarHandle mechanics - private static final VarHandle QHEAD; - private static final VarHandle QTAIL; - private static final VarHandle QCLEANME; - static { - try { - MethodHandles.Lookup l = MethodHandles.lookup(); - QHEAD = l.findVarHandle(TransferQueue.class, "head", - QNode.class); - QTAIL = l.findVarHandle(TransferQueue.class, "tail", - QNode.class); - QCLEANME = l.findVarHandle(TransferQueue.class, "cleanMe", - QNode.class); - } catch (ReflectiveOperationException e) { - throw new ExceptionInInitializerError(e); } } } /** - * The transferer. Set only in constructor, but cannot be declared - * as final without further complicating serialization. Since - * this is accessed only at most once per public method, there - * isn't a noticeable performance penalty for using volatile - * instead of final here. + * The transferer. (See below about serialization.) */ - private transient volatile Transferer transferer; + private final transient Transferer transferer; + + private final transient boolean fair; + + /** Invokes fair or lifo transfer */ + private Object xfer(Object e, long nanos) { + Transferer x = transferer; + return (fair) ? x.xfer(e, nanos) : x.xferLifo(e, nanos); + } /** * Creates a {@code SynchronousQueue} with nonfair access policy. @@ -824,7 +247,8 @@ * access; otherwise the order is unspecified. */ public SynchronousQueue(boolean fair) { - transferer = fair ? new TransferQueue() : new TransferStack(); + this.fair = fair; + transferer = new Transferer(); } /** @@ -835,11 +259,13 @@ * @throws NullPointerException {@inheritDoc} */ public void put(E e) throws InterruptedException { - if (e == null) throw new NullPointerException(); - if (transferer.transfer(e, false, 0) == null) { - Thread.interrupted(); - throw new InterruptedException(); + Objects.requireNonNull(e); + if (!Thread.interrupted()) { + if (xfer(e, Long.MAX_VALUE) == null) + return; + Thread.interrupted(); // failure possible only due to interrupt } + throw new InterruptedException(); } /** @@ -853,8 +279,9 @@ */ public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { - if (e == null) throw new NullPointerException(); - if (transferer.transfer(e, true, unit.toNanos(timeout)) != null) + Objects.requireNonNull(e); + long nanos = Math.max(unit.toNanos(timeout), 0L); + if (xfer(e, nanos) == null) return true; if (!Thread.interrupted()) return false; @@ -871,8 +298,8 @@ * @throws NullPointerException if the specified element is null */ public boolean offer(E e) { - if (e == null) throw new NullPointerException(); - return transferer.transfer(e, true, 0) != null; + Objects.requireNonNull(e); + return xfer(e, 0L) == null; } /** @@ -882,11 +309,14 @@ * @return the head of this queue * @throws InterruptedException {@inheritDoc} */ + @SuppressWarnings("unchecked") public E take() throws InterruptedException { - E e = transferer.transfer(null, false, 0); - if (e != null) - return e; - Thread.interrupted(); + Object e; + if (!Thread.interrupted()) { + if ((e = xfer(null, Long.MAX_VALUE)) != null) + return (E) e; + Thread.interrupted(); + } throw new InterruptedException(); } @@ -899,10 +329,12 @@ * specified waiting time elapses before an element is present * @throws InterruptedException {@inheritDoc} */ + @SuppressWarnings("unchecked") public E poll(long timeout, TimeUnit unit) throws InterruptedException { - E e = transferer.transfer(null, true, unit.toNanos(timeout)); - if (e != null || !Thread.interrupted()) - return e; + Object e; + long nanos = Math.max(unit.toNanos(timeout), 0L); + if ((e = xfer(null, nanos)) != null || !Thread.interrupted()) + return (E) e; throw new InterruptedException(); } @@ -913,8 +345,9 @@ * @return the head of this queue, or {@code null} if no * element is available */ + @SuppressWarnings("unchecked") public E poll() { - return transferer.transfer(null, true, 0); + return (E) xfer(null, 0L); } /** @@ -1104,11 +537,13 @@ } /* - * To cope with serialization strategy in the 1.5 version of - * SynchronousQueue, we declare some unused classes and fields - * that exist solely to enable serializability across versions. - * These fields are never used, so are initialized only if this - * object is ever serialized or deserialized. + * To cope with serialization across multiple implementation + * overhauls, we declare some unused classes and fields that exist + * solely to enable serializability across versions. These fields + * are never used, so are initialized only if this object is ever + * serialized. We use readResolve to replace a deserialized queue + * with a fresh one. Note that no queue elements are serialized, + * since any existing ones are only transient. */ @SuppressWarnings("serial") @@ -1130,7 +565,6 @@ */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { - boolean fair = transferer instanceof TransferQueue; if (fair) { qlock = new ReentrantLock(true); waitingProducers = new FifoWaitQueue(); @@ -1145,24 +579,10 @@ } /** - * Reconstitutes this queue from a stream (that is, deserializes it). - * @param s the stream - * @throws ClassNotFoundException if the class of a serialized object - * could not be found - * @throws java.io.IOException if an I/O error occurs + * Replaces a deserialized SynchronousQueue with a fresh one with + * the associated fairness */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - if (waitingProducers instanceof FifoWaitQueue) - transferer = new TransferQueue(); - else - transferer = new TransferStack(); - } - - static { - // Reduce the risk of rare disastrous classloading in first call to - // LockSupport.park: https://bugs.openjdk.org/browse/JDK-8074773 - Class ensureLoaded = LockSupport.class; + private Object readResolve() { + return new SynchronousQueue(waitingProducers instanceof FifoWaitQueue); } } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/CABI.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/CABI.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/CABI.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/CABI.java 2024-01-16 16:19:00.000000000 +0000 @@ -41,6 +41,7 @@ WIN_AARCH_64, LINUX_PPC_64_LE, LINUX_RISCV_64, + LINUX_S390, FALLBACK, UNSUPPORTED; @@ -81,7 +82,11 @@ if (OperatingSystem.isLinux()) { return LINUX_RISCV_64; } - } + } else if (arch.equals("s390x")) { + if (OperatingSystem.isLinux()) { + return LINUX_S390; + } + } } else if (FallbackLinker.isSupported()) { return FALLBACK; // fallback linker } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java 2024-01-16 16:19:00.000000000 +0000 @@ -32,6 +32,7 @@ import jdk.internal.foreign.abi.fallback.FallbackLinker; import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker; import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker; +import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker; import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; import jdk.internal.foreign.layout.AbstractLayout; @@ -60,7 +61,8 @@ public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker, SysVx64Linker, WindowsAArch64Linker, Windowsx64Linker, LinuxPPC64leLinker, - LinuxRISCV64Linker, FallbackLinker { + LinuxRISCV64Linker, LinuxS390Linker, + FallbackLinker { public interface UpcallStubFactory { MemorySegment makeStub(MethodHandle target, Arena arena); diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java 2024-01-16 16:19:00.000000000 +0000 @@ -35,6 +35,7 @@ import jdk.internal.foreign.abi.fallback.FallbackLinker; import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker; import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker; +import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker; import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; import jdk.internal.vm.annotation.ForceInline; @@ -242,6 +243,7 @@ case WIN_AARCH_64 -> WindowsAArch64Linker.getInstance(); case LINUX_PPC_64_LE -> LinuxPPC64leLinker.getInstance(); case LINUX_RISCV_64 -> LinuxRISCV64Linker.getInstance(); + case LINUX_S390 -> LinuxS390Linker.getInstance(); case FALLBACK -> FallbackLinker.getInstance(); case UNSUPPORTED -> throw new UnsupportedOperationException("Platform does not support native linker"); }; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023 IBM Corp. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.foreign.abi.s390; + +import jdk.internal.foreign.abi.ABIDescriptor; +import jdk.internal.foreign.abi.Architecture; +import jdk.internal.foreign.abi.StubLocations; +import jdk.internal.foreign.abi.VMStorage; + +public final class S390Architecture implements Architecture { + public static final Architecture INSTANCE = new S390Architecture(); + + // Needs to be consistent with vmstorage_s390.hpp. + public static final short REG32_MASK = 0b0000_0000_0000_0001; + public static final short REG64_MASK = 0b0000_0000_0000_0011; + + private static final int INTEGER_REG_SIZE = 8; + private static final int FLOAT_REG_SIZE = 8; + private static final int STACK_SLOT_SIZE = 8; + + // Suppresses default constructor, ensuring non-instantiability. + private S390Architecture() { + } + + @Override + public boolean isStackType(int cls) { + return cls == StorageType.STACK; + } + + @Override + public int typeSize(int cls) { + switch (cls) { + case StorageType.INTEGER: + return INTEGER_REG_SIZE; + case StorageType.FLOAT: + return FLOAT_REG_SIZE; + // STACK is deliberately omitted + } + + throw new IllegalArgumentException("Invalid Storage Class: " + cls); + } + + public interface StorageType { + byte INTEGER = 0; + byte FLOAT = 1; + byte STACK = 2; + byte PLACEHOLDER = 3; + } + + public static class Regs { // break circular dependency + public static final VMStorage r0 = integerRegister(0); + public static final VMStorage r1 = integerRegister(1); + public static final VMStorage r2 = integerRegister(2); + public static final VMStorage r3 = integerRegister(3); + public static final VMStorage r4 = integerRegister(4); + public static final VMStorage r5 = integerRegister(5); + public static final VMStorage r6 = integerRegister(6); + public static final VMStorage r7 = integerRegister(7); + public static final VMStorage r8 = integerRegister(8); + public static final VMStorage r9 = integerRegister(9); + public static final VMStorage r10 = integerRegister(10); + public static final VMStorage r11 = integerRegister(11); + public static final VMStorage r12 = integerRegister(12); + public static final VMStorage r13 = integerRegister(13); + public static final VMStorage r14 = integerRegister(14); + public static final VMStorage r15 = integerRegister(15); + + public static final VMStorage f0 = floatRegister(0); + public static final VMStorage f1 = floatRegister(1); + public static final VMStorage f2 = floatRegister(2); + public static final VMStorage f3 = floatRegister(3); + public static final VMStorage f4 = floatRegister(4); + public static final VMStorage f5 = floatRegister(5); + public static final VMStorage f6 = floatRegister(6); + public static final VMStorage f7 = floatRegister(7); + public static final VMStorage f8 = floatRegister(8); + public static final VMStorage f9 = floatRegister(9); + public static final VMStorage f10 = floatRegister(10); + public static final VMStorage f11 = floatRegister(11); + public static final VMStorage f12 = floatRegister(12); + public static final VMStorage f13 = floatRegister(13); + public static final VMStorage f14 = floatRegister(14); + public static final VMStorage f15 = floatRegister(15); + } + + private static VMStorage integerRegister(int index) { + return new VMStorage(StorageType.INTEGER, REG64_MASK, index, "r" + index); + } + + private static VMStorage floatRegister(int index) { + return new VMStorage(StorageType.FLOAT, REG64_MASK, index, "f" + index); + } + + public static VMStorage stackStorage(short size, int byteOffset) { + return new VMStorage(StorageType.STACK, size, byteOffset); + } + + public static ABIDescriptor abiFor(VMStorage[] inputIntRegs, + VMStorage[] inputFloatRegs, + VMStorage[] outputIntRegs, + VMStorage[] outputFloatRegs, + VMStorage[] volatileIntRegs, + VMStorage[] volatileFloatRegs, + int stackAlignment, + int shadowSpace, + VMStorage scratch1, VMStorage scratch2) { + return new ABIDescriptor( + INSTANCE, + new VMStorage[][] { + inputIntRegs, + inputFloatRegs, + }, + new VMStorage[][] { + outputIntRegs, + outputFloatRegs, + }, + new VMStorage[][] { + volatileIntRegs, + volatileFloatRegs, + }, + stackAlignment, + shadowSpace, + scratch1, scratch2, + StubLocations.TARGET_ADDRESS.storage(StorageType.PLACEHOLDER), + StubLocations.RETURN_BUFFER.storage(StorageType.PLACEHOLDER), + StubLocations.CAPTURED_STATE_BUFFER.storage(StorageType.PLACEHOLDER)); + } +} diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023 IBM Corp. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.foreign.abi.s390.linux; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import jdk.internal.foreign.abi.ABIDescriptor; +import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory; +import jdk.internal.foreign.abi.Binding; +import jdk.internal.foreign.abi.CallingSequence; +import jdk.internal.foreign.abi.CallingSequenceBuilder; +import jdk.internal.foreign.abi.DowncallLinker; +import jdk.internal.foreign.abi.LinkerOptions; +import jdk.internal.foreign.abi.UpcallLinker; +import jdk.internal.foreign.abi.SharedUtils; +import jdk.internal.foreign.abi.VMStorage; +import jdk.internal.foreign.Utils; + +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static jdk.internal.foreign.abi.s390.linux.TypeClass.*; +import static jdk.internal.foreign.abi.s390.S390Architecture.*; +import static jdk.internal.foreign.abi.s390.S390Architecture.Regs.*; + +/** + * For the S390 C ABI specifically, this class uses CallingSequenceBuilder + * to translate a C FunctionDescriptor into a CallingSequence, which can then be turned into a MethodHandle. + * + * This includes taking care of synthetic arguments like pointers to return buffers for 'in-memory' returns. + */ +public class LinuxS390CallArranger { + + private static final int STACK_SLOT_SIZE = 8; + public static final int MAX_REGISTER_ARGUMENTS = 5; + public static final int MAX_FLOAT_REGISTER_ARGUMENTS = 4; + + private static final ABIDescriptor CLinux = abiFor( + new VMStorage[] { r2, r3, r4, r5, r6, }, // GP input + new VMStorage[] { f0, f2, f4, f6 }, // FP input + new VMStorage[] { r2, }, // GP output + new VMStorage[] { f0, }, // FP output + new VMStorage[] { r0, r1, r2, r3, r4, r5, r14 }, // volatile GP + new VMStorage[] { f1, f3, f5, f7 }, // volatile FP (excluding argument registers) + 8, // Stack is always 8 byte aligned on S390 + 160, // ABI header + r0, r1 // scratch reg r0 & r1 + ); + + public record Bindings(CallingSequence callingSequence, boolean isInMemoryReturn) {} + + public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall) { + return getBindings(mt, cDesc, forUpcall, LinkerOptions.empty()); + } + + public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall, LinkerOptions options) { + CallingSequenceBuilder csb = new CallingSequenceBuilder(CLinux, forUpcall, options); + + BindingCalculator argCalc = forUpcall ? new BoxBindingCalculator(true) : new UnboxBindingCalculator(true); + BindingCalculator retCalc = forUpcall ? new UnboxBindingCalculator(false) : new BoxBindingCalculator(false); + + boolean returnInMemory = isInMemoryReturn(cDesc.returnLayout()); + if (returnInMemory) { + Class carrier = MemorySegment.class; + MemoryLayout layout =SharedUtils.C_POINTER; + csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout)); + } else if (cDesc.returnLayout().isPresent()) { + Class carrier = mt.returnType(); + MemoryLayout layout = cDesc.returnLayout().get(); + csb.setReturnBindings(carrier, layout, retCalc.getBindings(carrier, layout)); + } + + for (int i = 0; i < mt.parameterCount(); i++) { + Class carrier = mt.parameterType(i); + MemoryLayout layout = cDesc.argumentLayouts().get(i); + csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout)); + } + + return new Bindings(csb.build(), returnInMemory); + } + + public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) { + Bindings bindings = getBindings(mt, cDesc, false, options); + + MethodHandle handle = new DowncallLinker(CLinux, bindings.callingSequence).getBoundMethodHandle(); + + if (bindings.isInMemoryReturn) { + handle = SharedUtils.adaptDowncallForIMR(handle, cDesc, bindings.callingSequence); + } + + return handle; + } + + public static UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) { + Bindings bindings = getBindings(mt, cDesc, true, options); + + final boolean dropReturn = true; /* drop return, since we don't have bindings for it */ + return SharedUtils.arrangeUpcallHelper(mt, bindings.isInMemoryReturn, dropReturn, CLinux, + bindings.callingSequence); + } + + private static boolean isInMemoryReturn(Optional returnLayout) { + return returnLayout + .filter(layout -> layout instanceof GroupLayout) + .isPresent(); + } + + static class StorageCalculator { + private final boolean forArguments; + + private final int[] nRegs = new int[] { 0, 0 }; + private long stackOffset = 0; + + public StorageCalculator(boolean forArguments) { + this.forArguments = forArguments; + } + + VMStorage stackAlloc(long size, long alignment) { + long alignedStackOffset = Utils.alignUp(stackOffset, alignment); + + short encodedSize = (short) size; + assert (encodedSize & 0xFFFF) == size; + + VMStorage storage = stackStorage(encodedSize, (int) alignedStackOffset); + stackOffset = alignedStackOffset + size; + return storage; + } + + VMStorage regAlloc(int type) { + int gpRegCnt = (type == StorageType.INTEGER) ? 1 : 0; + int fpRegCnt = (type == StorageType.FLOAT) ? 1 : 0; + + // Use stack if not enough registers available. + if ((type == StorageType.FLOAT && (nRegs[StorageType.FLOAT] + fpRegCnt) > MAX_FLOAT_REGISTER_ARGUMENTS) + || (type == StorageType.INTEGER && (nRegs[StorageType.INTEGER] + gpRegCnt) > MAX_REGISTER_ARGUMENTS)) return null; + + VMStorage[] source = (forArguments ? CLinux.inputStorage : CLinux.outputStorage)[type]; + VMStorage result = source[nRegs[type]]; + + nRegs[StorageType.INTEGER] += gpRegCnt; + nRegs[StorageType.FLOAT] += fpRegCnt; + return result; + + } + VMStorage getStorage(int type, boolean is32Bit) { + VMStorage reg = regAlloc(type); + if (reg != null) { + if (is32Bit) { + reg = new VMStorage(reg.type(), REG32_MASK, reg.indexOrOffset()); + } + return reg; + } + VMStorage stack; + if (is32Bit) { + stackAlloc(4, STACK_SLOT_SIZE); // Skip first half of stack slot. + stack = stackAlloc(4, 4); + } else + stack = stackAlloc(8, STACK_SLOT_SIZE); + + return stack; + } + } + + abstract static class BindingCalculator { + protected final StorageCalculator storageCalculator; + + protected BindingCalculator(boolean forArguments) { + this.storageCalculator = new LinuxS390CallArranger.StorageCalculator(forArguments); + } + + abstract List getBindings(Class carrier, MemoryLayout layout); + } + + // Compute recipe for transferring arguments / return values to C from Java. + static class UnboxBindingCalculator extends BindingCalculator { + UnboxBindingCalculator(boolean forArguments) { + super(forArguments); + } + + @Override + List getBindings(Class carrier, MemoryLayout layout) { + TypeClass argumentClass = TypeClass.classifyLayout(layout); + Binding.Builder bindings = Binding.builder(); + switch (argumentClass) { + case STRUCT_REGISTER -> { + assert carrier == MemorySegment.class; + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), false); + bindings.bufferLoad(0, type) + .vmStore(storage, type); + } + case STRUCT_SFA -> { + assert carrier == MemorySegment.class; + VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, layout.byteSize() == 4); + Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), true); + bindings.bufferLoad(0, type) + .vmStore(storage, type); + } + case STRUCT_REFERENCE -> { + assert carrier == MemorySegment.class; + bindings.copy(layout) + .unboxAddress(); + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + bindings.vmStore(storage, long.class); + } + case POINTER -> { + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + bindings.unboxAddress() + .vmStore(storage, long.class); + } + case INTEGER -> { + // ABI requires all int types to get extended to 64 bit. + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + bindings.vmStore(storage, carrier); + } + case FLOAT -> { + VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, carrier == float.class); + bindings.vmStore(storage, carrier); + } + default -> throw new UnsupportedOperationException("Unhandled class " + argumentClass); + } + return bindings.build(); + } + } + + // Compute recipe for transferring arguments / return values from C to Java. + static class BoxBindingCalculator extends BindingCalculator { + BoxBindingCalculator(boolean forArguments) { + super(forArguments); + } + + @Override + List getBindings(Class carrier, MemoryLayout layout) { + TypeClass argumentClass = TypeClass.classifyLayout(layout); + Binding.Builder bindings = Binding.builder(); + switch (argumentClass) { + case STRUCT_REGISTER -> { + assert carrier == MemorySegment.class; + bindings.allocate(layout) + .dup(); + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), false); + bindings.vmLoad(storage, type) + .bufferStore(0, type); + } + case STRUCT_SFA -> { + assert carrier == MemorySegment.class; + bindings.allocate(layout) + .dup(); + VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, layout.byteSize() == 4); + Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), true); + bindings.vmLoad(storage, type) + .bufferStore(0, type); + } + case STRUCT_REFERENCE -> { + assert carrier == MemorySegment.class; + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + bindings.vmLoad(storage, long.class) + .boxAddress(layout); + } + case POINTER -> { + AddressLayout addressLayout = (AddressLayout) layout; + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + bindings.vmLoad(storage, long.class) + .boxAddressRaw(Utils.pointeeByteSize(addressLayout), Utils.pointeeByteAlign(addressLayout)); + } + case INTEGER -> { + // We could use carrier != long.class for BoxBindingCalculator, but C always uses 64 bit slots. + VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); + bindings.vmLoad(storage, carrier); + } + case FLOAT -> { + VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, carrier == float.class); + bindings.vmLoad(storage, carrier); + } + default -> throw new UnsupportedOperationException("Unhandled class " + argumentClass); + } + return bindings.build(); + } + } +} diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023 IBM Corp. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.foreign.abi.s390.linux; + +import jdk.internal.foreign.abi.AbstractLinker; +import jdk.internal.foreign.abi.LinkerOptions; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.nio.ByteOrder; + +public final class LinuxS390Linker extends AbstractLinker { + + public static LinuxS390Linker getInstance() { + final class Holder { + private static final LinuxS390Linker INSTANCE = new LinuxS390Linker(); + } + + return Holder.INSTANCE; + } + + private LinuxS390Linker() { + // Ensure there is only one instance + } + + @Override + protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function, LinkerOptions options) { + return LinuxS390CallArranger.arrangeDowncall(inferredMethodType, function, options); + } + + @Override + protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function, LinkerOptions options) { + return LinuxS390CallArranger.arrangeUpcall(targetType, function, options); + } + + @Override + protected ByteOrder linkerByteOrder() { + return ByteOrder.BIG_ENDIAN; + } +} diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023 IBM Corp. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.foreign.abi.s390.linux; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.ValueLayout; +import java.util.List; +import java.util.ArrayList; + +public enum TypeClass { + STRUCT_REGISTER, + STRUCT_SFA, // Single Float Aggregate + STRUCT_REFERENCE, + POINTER, + INTEGER, + FLOAT; + + private static TypeClass classifyValueType(ValueLayout type) { + Class carrier = type.carrier(); + if (carrier == boolean.class || carrier == byte.class || carrier == char.class || + carrier == short.class || carrier == int.class || carrier == long.class) { + return INTEGER; + } else if (carrier == float.class || carrier == double.class) { + return FLOAT; + } else if (carrier == MemorySegment.class) { + return POINTER; + } else { + throw new IllegalStateException("Cannot get here: " + carrier.getName()); + } + } + + private static boolean isRegisterAggregate(MemoryLayout type) { + long byteSize = type.byteSize(); + if (byteSize > 8 || byteSize == 3 || byteSize == 5 || byteSize == 6 || byteSize == 7) + return false; + return true; + } + + static List scalarLayouts(GroupLayout gl) { + List out = new ArrayList<>(); + scalarLayoutsInternal(out, gl); + return out; + } + + private static void scalarLayoutsInternal(List out, GroupLayout gl) { + for (MemoryLayout member : gl.memberLayouts()) { + if (member instanceof GroupLayout memberGl) { + scalarLayoutsInternal(out, memberGl); + } else if (member instanceof SequenceLayout memberSl) { + for (long i = 0; i < memberSl.elementCount(); i++) { + out.add(memberSl.elementLayout()); + } + } else { + // padding or value layouts + out.add(member); + } + } + } + + static boolean isSingleFloatAggregate(MemoryLayout type) { + List scalarLayouts = scalarLayouts((GroupLayout) type); + + final int numElements = scalarLayouts.size(); + if (numElements > 1 || numElements == 0) + return false; + + MemoryLayout baseType = scalarLayouts.get(0); + + if (!(baseType instanceof ValueLayout)) + return false; + + TypeClass baseArgClass = classifyValueType((ValueLayout) baseType); + if (baseArgClass != FLOAT) + return false; + + return true; + } + + private static TypeClass classifyStructType(MemoryLayout layout) { + + if (!isRegisterAggregate(layout)) { + return TypeClass.STRUCT_REFERENCE; + } + + if (isSingleFloatAggregate(layout)) { + return TypeClass.STRUCT_SFA; + } + return TypeClass.STRUCT_REGISTER; + } + + public static TypeClass classifyLayout(MemoryLayout type) { + if (type instanceof ValueLayout) { + return classifyValueType((ValueLayout) type); + } else if (type instanceof GroupLayout) { + return classifyStructType(type); + } else { + throw new IllegalArgumentException("Unsupported layout: " + type); + } + } +} diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, 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 @@ -38,7 +38,6 @@ import java.util.function.Supplier; import java.lang.System.LoggerFinder; import java.lang.System.Logger; -import java.lang.System.Logger.Level; import java.lang.ref.WeakReference; import java.util.Objects; import java.util.concurrent.ExecutionException; @@ -227,9 +226,19 @@ // The accessor in which this logger is temporarily set. final LazyLoggerAccessor holder; + // tests whether the logger is invoked by the loading thread before + // the LoggerFinder is loaded; can be null; + final BooleanSupplier isLoadingThread; - BootstrapLogger(LazyLoggerAccessor holder) { + // returns true if the logger is invoked by the loading thread before the + // LoggerFinder service is loaded + boolean isLoadingThread() { + return isLoadingThread != null && isLoadingThread.getAsBoolean(); + } + + BootstrapLogger(LazyLoggerAccessor holder, BooleanSupplier isLoadingThread) { this.holder = holder; + this.isLoadingThread = isLoadingThread; } // Temporary data object storing log events @@ -505,14 +514,15 @@ static void log(LogEvent log, PlatformLogger.Bridge logger) { final SecurityManager sm = System.getSecurityManager(); if (sm == null || log.acc == null) { - log.log(logger); + BootstrapExecutors.submit(() -> log.log(logger)); } else { // not sure we can actually use lambda here. We may need to create // an anonymous class. Although if we reach here, then it means // the VM is booted. - AccessController.doPrivileged((PrivilegedAction) () -> { - log.log(logger); return null; - }, log.acc); + BootstrapExecutors.submit(() -> + AccessController.doPrivileged((PrivilegedAction) () -> { + log.log(logger); return null; + }, log.acc)); } } @@ -559,8 +569,9 @@ * @return true if the VM is still bootstrapping. */ boolean checkBootstrapping() { - if (isBooted()) { + if (isBooted() && !isLoadingThread()) { BootstrapExecutors.flush(); + holder.getConcreteLogger(this); return false; } return true; @@ -935,10 +946,16 @@ // - the logging backend is a custom backend // - the logging backend is JUL, there is no custom config, // and the LogManager has not been initialized yet. - public static synchronized boolean useLazyLoggers() { - return !BootstrapLogger.isBooted() - || DetectBackend.detectedBackend == LoggingBackend.CUSTOM - || useSurrogateLoggers(); + public static boolean useLazyLoggers() { + // Note: avoid triggering the initialization of the DetectBackend class + // while holding the BootstrapLogger class monitor + if (!BootstrapLogger.isBooted() || + DetectBackend.detectedBackend == LoggingBackend.CUSTOM) { + return true; + } + synchronized (BootstrapLogger.class) { + return useSurrogateLoggers(); + } } // Called by LazyLoggerAccessor. This method will determine whether @@ -946,9 +963,9 @@ // a SurrogateLogger (if JUL is the default backend and there // is no custom JUL configuration and LogManager is not yet initialized), // or a logger returned by the loaded LoggerFinder (all other cases). - static Logger getLogger(LazyLoggerAccessor accessor) { - if (!BootstrapLogger.isBooted()) { - return new BootstrapLogger(accessor); + static Logger getLogger(LazyLoggerAccessor accessor, BooleanSupplier isLoading) { + if (!BootstrapLogger.isBooted() || isLoading != null && isLoading.getAsBoolean()) { + return new BootstrapLogger(accessor, isLoading); } else { if (useSurrogateLoggers()) { // JUL is the default backend, there is no custom configuration, @@ -964,6 +981,12 @@ } } + // trigger class initialization outside of holding lock + static void ensureBackendDetected() { + assert VM.isBooted() : "VM is not booted"; + // triggers detection of the backend + var backend = DetectBackend.detectedBackend; + } // If the backend is JUL, and there is no custom configuration, and // nobody has attempted to call LogManager.getLogManager() yet, then diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, 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 @@ -32,6 +32,9 @@ import java.lang.System.Logger; import java.lang.ref.WeakReference; import java.util.Objects; +import java.util.function.BooleanSupplier; + +import jdk.internal.logger.LoggerFinderLoader.TemporaryLoggerFinder; import jdk.internal.misc.VM; import sun.util.logging.PlatformLogger; @@ -110,6 +113,9 @@ // We need to pass the actual caller module when creating the logger. private final WeakReference moduleRef; + // whether this is the loading thread, can be null + private final BooleanSupplier isLoadingThread; + // The name of the logger that will be created lazyly final String name; // The plain logger SPI object - null until it is accessed for the @@ -122,16 +128,24 @@ private LazyLoggerAccessor(String name, LazyLoggerFactories factories, Module module) { + this(name, factories, module, null); + } + + private LazyLoggerAccessor(String name, + LazyLoggerFactories factories, + Module module, BooleanSupplier isLoading) { + this(Objects.requireNonNull(name), Objects.requireNonNull(factories), - Objects.requireNonNull(module), null); + Objects.requireNonNull(module), isLoading, null); } private LazyLoggerAccessor(String name, LazyLoggerFactories factories, - Module module, Void unused) { + Module module, BooleanSupplier isLoading, Void unused) { this.name = name; this.factories = factories; this.moduleRef = new WeakReference<>(module); + this.isLoadingThread = isLoading; } /** @@ -162,7 +176,7 @@ // BootstrapLogger has the logic to decide whether to invoke the // SPI or use a temporary (BootstrapLogger or SimpleConsoleLogger) // logger. - wrapped = BootstrapLogger.getLogger(this); + wrapped = BootstrapLogger.getLogger(this, isLoadingThread); synchronized(this) { // if w has already been in between, simply drop 'wrapped'. setWrappedIfNotSet(wrapped); @@ -194,7 +208,7 @@ // BootstrapLogger has the logic to decide whether to invoke the // SPI or use a temporary (BootstrapLogger or SimpleConsoleLogger) // logger. - final Logger wrapped = BootstrapLogger.getLogger(this); + final Logger wrapped = BootstrapLogger.getLogger(this, isLoadingThread); synchronized(this) { // if w has already been set, simply drop 'wrapped'. setWrappedIfNotSet(wrapped); @@ -282,10 +296,10 @@ * Creates a new lazy logger accessor for the named logger. The given * factories will be use when it becomes necessary to actually create * the logger. - * @param An interface that extends {@link Logger}. * @param name The logger name. * @param factories The factories that should be used to create the * wrapped logger. + * @param module The module for which the logger is being created * @return A new LazyLoggerAccessor. */ public static LazyLoggerAccessor makeAccessor(String name, @@ -340,6 +354,7 @@ prov = sm == null ? LoggerFinder.getLoggerFinder() : AccessController.doPrivileged( (PrivilegedAction)LoggerFinder::getLoggerFinder); + if (prov instanceof TemporaryLoggerFinder) return prov; provider = prov; } return prov; @@ -359,7 +374,6 @@ new LazyLoggerFactories<>(loggerSupplier); - // A concrete implementation of Logger that delegates to a System.Logger, // but only creates the System.Logger instance lazily when it's used for // the first time. @@ -377,6 +391,11 @@ } } + static Logger makeLazyLogger(String name, Module module, BooleanSupplier isLoading) { + final LazyLoggerAccessor holder = new LazyLoggerAccessor(name, factories, module, isLoading); + return new JdkLazyLogger(holder, null); + } + /** * Gets a logger from the LoggerFinder. Creates the actual concrete * logger. diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -25,6 +25,8 @@ package jdk.internal.logger; import java.io.FilePermission; +import java.lang.System.Logger; +import java.lang.System.LoggerFinder; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; @@ -32,6 +34,9 @@ import java.util.Locale; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; +import java.util.function.BooleanSupplier; + +import jdk.internal.vm.annotation.Stable; import sun.security.util.SecurityConstants; import sun.security.action.GetBooleanAction; import sun.security.action.GetPropertyAction; @@ -65,13 +70,28 @@ throw new InternalError("LoggerFinderLoader cannot be instantiated"); } - + // record the loadingThread while loading the backend + static volatile Thread loadingThread; // Return the loaded LoggerFinder, or load it if not already loaded. private static System.LoggerFinder service() { if (service != null) return service; + // ensure backend is detected before attempting to load the finder + BootstrapLogger.ensureBackendDetected(); synchronized(lock) { if (service != null) return service; - service = loadLoggerFinder(); + Thread currentThread = Thread.currentThread(); + if (loadingThread == currentThread) { + // recursive attempt to load the backend while loading the backend + // use a temporary logger finder that returns special BootstrapLogger + // which will wait until loading is finished + return TemporaryLoggerFinder.INSTANCE; + } + loadingThread = currentThread; + try { + service = loadLoggerFinder(); + } finally { + loadingThread = null; + } } // Since the LoggerFinder is already loaded - we can stop using // temporary loggers. @@ -79,6 +99,12 @@ return service; } + // returns true if called by the thread that loads the LoggerFinder, while + // loading the LoggerFinder. + static boolean isLoadingThread() { + return loadingThread != null && loadingThread == Thread.currentThread(); + } + // Get configuration error policy private static ErrorPolicy configurationErrorPolicy() { String errorPolicy = @@ -117,6 +143,34 @@ return iterator; } + public static final class TemporaryLoggerFinder extends LoggerFinder { + private TemporaryLoggerFinder() {} + @Stable + private LoggerFinder loadedService; + + private static final BooleanSupplier isLoadingThread = new BooleanSupplier() { + @Override + public boolean getAsBoolean() { + return LoggerFinderLoader.isLoadingThread(); + } + }; + private static final TemporaryLoggerFinder INSTANCE = new TemporaryLoggerFinder(); + + @Override + public Logger getLogger(String name, Module module) { + if (loadedService == null) { + loadedService = service; + if (loadedService == null) { + return LazyLoggers.makeLazyLogger(name, module, isLoadingThread); + } + } + assert loadedService != null; + assert !LoggerFinderLoader.isLoadingThread(); + assert loadedService != this; + return LazyLoggers.getLogger(name, module); + } + } + // Loads the LoggerFinder using ServiceLoader. If no LoggerFinder // is found returns the default (possibly JUL based) implementation private static System.LoggerFinder loadLoggerFinder() { diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/util/Architecture.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/util/Architecture.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/util/Architecture.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/util/Architecture.java 2024-01-16 16:19:00.000000000 +0000 @@ -25,6 +25,8 @@ package jdk.internal.util; import jdk.internal.vm.annotation.ForceInline; + +import java.nio.ByteOrder; import java.util.Locale; /** @@ -35,19 +37,83 @@ * architecture values. */ public enum Architecture { - OTHER, // An unknown architecture not specifically named - X64, // Represents AMD64 and X86_64 - X86, - AARCH64, - ARM, - RISCV64, - LOONGARCH64, - S390, - PPC64, - MIPSEL, - MIPS64EL + /* + * An unknown architecture not specifically named. + * The addrSize and ByteOrder values are those of the current architecture. + */ + AARCH64(64, ByteOrder.LITTLE_ENDIAN), + ARM(32, ByteOrder.LITTLE_ENDIAN), + LOONGARCH64(64, ByteOrder.LITTLE_ENDIAN), + MIPSEL(32, ByteOrder.LITTLE_ENDIAN), + MIPS64EL(64, ByteOrder.LITTLE_ENDIAN), + OTHER(is64bit() ? 64 : 32, ByteOrder.nativeOrder()), + PPC(32, ByteOrder.BIG_ENDIAN), + PPC64(64, ByteOrder.BIG_ENDIAN), + PPC64LE(64, ByteOrder.LITTLE_ENDIAN), + RISCV64(64, ByteOrder.LITTLE_ENDIAN), + S390(64, ByteOrder.BIG_ENDIAN), + SPARCV9(64, ByteOrder.BIG_ENDIAN), + X86(32, ByteOrder.LITTLE_ENDIAN), + X64(64, ByteOrder.LITTLE_ENDIAN), // Represents AMD64 and X86_64 ; + private final int addrSize; + private final ByteOrder byteOrder; + + /** + * Construct an Architecture with number of address bits and byte order. + * @param addrSize number of address bits, typically 64 or 32 + * @param byteOrder the byte order, big-endian or little-endian + */ + Architecture(int addrSize, ByteOrder byteOrder) { + this.addrSize = addrSize; + this.byteOrder = byteOrder; + } + + /** + * {@return the number of address bits, typically 64 or 32} + */ + public int addressSize() { + return addrSize; + } + + /** + * {@return the byte order, {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}} + */ + public ByteOrder byteOrder() { + return byteOrder; + } + + /** + * {@return the Architecture by name or an alias for the architecture} + * The names are mapped to upper case before mapping to an Architecture. + * @param archName an Architecture name or alias for the architecture. + * @throws IllegalArgumentException if the name is not an alias or an Architecture name + */ + public static Architecture lookupByName(String archName) { + archName = archName.toUpperCase(Locale.ROOT); // normalize to uppercase + return switch (archName) { + case "X86_64", "AMD64" -> X64; + case "I386" -> X86; + case "S390X" -> S390; + default -> Architecture.valueOf(archName); + }; + } + + /** + * Returns the Architecture of the built architecture. + * Build time names are mapped to respective uppercase enum values. + * Names not recognized are mapped to Architecture.OTHER. + */ + private static Architecture initArch(String archName) { + try { + return lookupByName(archName); + } catch (IllegalArgumentException ile) { + return Architecture.OTHER; + } + } + + // Initialize the architecture by mapping aliases and names to the enum values. private static Architecture CURRENT_ARCH = initArch(PlatformProps.CURRENT_ARCH_STRING); /** @@ -91,8 +157,15 @@ } /** - * {@return {@code true} if the current architecture is PPC64} - * Use {@link #isLittleEndian()} to determine big or little endian. + * {@return {@code true} if the current architecture is PPC, big-endian} + */ + @ForceInline + public static boolean isPPC() { + return PlatformProps.TARGET_ARCH_IS_PPC; + } + + /** + * {@return {@code true} if the current architecture is PPC64, big-endian} */ @ForceInline public static boolean isPPC64() { @@ -100,6 +173,14 @@ } /** + * {@return {@code true} if the current architecture is PPC64, little-endian} + */ + @ForceInline + public static boolean isPPC64LE() { + return PlatformProps.TARGET_ARCH_IS_PPC64LE; + } + + /** * {@return {@code true} if the current architecture is ARM} */ @ForceInline @@ -132,6 +213,14 @@ } /** + * {@return {@code true} if the current architecture is SPARCV9} + */ + @ForceInline + public static boolean isSPARCV9() { + return PlatformProps.TARGET_ARCH_IS_SPARCV9; + } + + /** * {@return the current architecture} */ public static Architecture current() { @@ -153,18 +242,4 @@ public static boolean isLittleEndian() { return PlatformProps.TARGET_ARCH_LITTLE_ENDIAN; } - - - /** - * Returns the Architecture of the built architecture. - * Build time names are mapped to respective uppercase enum values. - * Names not recognized are mapped to Architecture.OTHER. - */ - private static Architecture initArch(String archName) { - try { - return Architecture.valueOf(archName.toUpperCase(Locale.ROOT)); - } catch (IllegalArgumentException ile) { - return Architecture.OTHER; - } - } } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template 2024-01-16 16:19:00.000000000 +0000 @@ -52,14 +52,18 @@ // Precomputed booleans for each Architecture, shared with jdk.internal.util.Architecture // The variables are named to match the Architecture value names, and // the values chosen to match the build values. - static final boolean TARGET_ARCH_IS_X64 = "@@OPENJDK_TARGET_CPU@@" == "x64"; - static final boolean TARGET_ARCH_IS_X86 = "@@OPENJDK_TARGET_CPU@@" == "x86"; static final boolean TARGET_ARCH_IS_AARCH64 = "@@OPENJDK_TARGET_CPU@@" == "aarch64"; static final boolean TARGET_ARCH_IS_ARM = "@@OPENJDK_TARGET_CPU@@" == "arm"; - static final boolean TARGET_ARCH_IS_RISCV64 = "@@OPENJDK_TARGET_CPU@@" == "riscv64"; static final boolean TARGET_ARCH_IS_LOONGARCH64 = "@@OPENJDK_TARGET_CPU@@" == "loongarch64"; - static final boolean TARGET_ARCH_IS_S390 = "@@OPENJDK_TARGET_CPU@@" == "s390"; - static final boolean TARGET_ARCH_IS_PPC64 = "@@OPENJDK_TARGET_CPU@@" == "ppc64"; static final boolean TARGET_ARCH_IS_MIPSEL = "@@OPENJDK_TARGET_CPU@@" == "mipsel"; static final boolean TARGET_ARCH_IS_MIPS64EL= "@@OPENJDK_TARGET_CPU@@" == "mips64el"; + static final boolean TARGET_ARCH_IS_PPC = "@@OPENJDK_TARGET_CPU@@" == "ppc"; + static final boolean TARGET_ARCH_IS_PPC64 = "@@OPENJDK_TARGET_CPU@@" == "ppc64"; + static final boolean TARGET_ARCH_IS_PPC64LE = "@@OPENJDK_TARGET_CPU@@" == "ppc64le"; + static final boolean TARGET_ARCH_IS_RISCV64 = "@@OPENJDK_TARGET_CPU@@" == "riscv64"; + static final boolean TARGET_ARCH_IS_S390 = "@@OPENJDK_TARGET_CPU@@" == "s390"; + static final boolean TARGET_ARCH_IS_SPARCV9 = "@@OPENJDK_TARGET_CPU@@" == "sparcv9"; + static final boolean TARGET_ARCH_IS_X86 = "@@OPENJDK_TARGET_CPU@@" == "x86"; + static final boolean TARGET_ARCH_IS_X64 = "@@OPENJDK_TARGET_CPU@@" == "x64"; + } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java 2024-01-16 16:19:00.000000000 +0000 @@ -24,6 +24,7 @@ */ package jdk.internal.vm; +import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -110,7 +111,8 @@ : new OpenOption[] { StandardOpenOption.CREATE_NEW }; String reply; try (OutputStream out = Files.newOutputStream(path, options); - PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8)) { + BufferedOutputStream bos = new BufferedOutputStream(out); + PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8)) { if (json) { dumpThreadsToJson(ps); } else { @@ -132,11 +134,12 @@ * This method is invoked by HotSpotDiagnosticMXBean.dumpThreads. */ public static void dumpThreads(OutputStream out) { - PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8); + BufferedOutputStream bos = new BufferedOutputStream(out); + PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8); try { dumpThreads(ps); } finally { - ps.flush(); + ps.flush(); // flushes underlying stream } } @@ -158,9 +161,10 @@ private static void dumpThread(Thread thread, PrintStream ps) { String suffix = thread.isVirtual() ? " virtual" : ""; - ps.format("#%d \"%s\"%s%n", thread.threadId(), thread.getName(), suffix); + ps.println("#" + thread.threadId() + " \"" + thread.getName() + "\"" + suffix); for (StackTraceElement ste : thread.getStackTrace()) { - ps.format(" %s%n", ste); + ps.print(" "); + ps.println(ste); } ps.println(); } @@ -171,11 +175,12 @@ * This method is invoked by HotSpotDiagnosticMXBean.dumpThreads. */ public static void dumpThreadsToJson(OutputStream out) { - PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8); + BufferedOutputStream bos = new BufferedOutputStream(out); + PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8); try { dumpThreadsToJson(ps); } finally { - ps.flush(); + ps.flush(); // flushes underlying stream } } @@ -257,13 +262,16 @@ */ private static void dumpThreadToJson(Thread thread, PrintStream out, boolean more) { out.println(" {"); - out.format(" \"tid\": \"%d\",%n", thread.threadId()); - out.format(" \"name\": \"%s\",%n", escape(thread.getName())); - out.format(" \"stack\": [%n"); + out.println(" \"tid\": \"" + thread.threadId() + "\","); + out.println(" \"name\": \"" + escape(thread.getName()) + "\","); + out.println(" \"stack\": ["); + int i = 0; StackTraceElement[] stackTrace = thread.getStackTrace(); while (i < stackTrace.length) { - out.format(" \"%s\"", escape(stackTrace[i].toString())); + out.print(" \""); + out.print(escape(stackTrace[i].toString())); + out.print("\""); i++; if (i < stackTrace.length) { out.println(","); diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java 2024-01-16 16:19:00.000000000 +0000 @@ -33,6 +33,7 @@ import java.lang.invoke.VarHandle; import java.lang.ref.Cleaner.Cleanable; import java.lang.reflect.Method; +import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.Inet4Address; import java.net.Inet6Address; @@ -650,114 +651,130 @@ } /** - * Receives a datagram into the given buffer. + * Receives a datagram. * - * @apiNote This method is for use by the socket adaptor. The buffer is - * assumed to be trusted, meaning it is not accessible to user code. + * @apiNote This method is for use by the socket adaptor. * * @throws IllegalBlockingModeException if the channel is non-blocking * @throws SocketTimeoutException if the timeout elapses */ - SocketAddress blockingReceive(ByteBuffer dst, long nanos) throws IOException { + void blockingReceive(DatagramPacket p, long nanos) throws IOException { + Objects.requireNonNull(p); + assert nanos >= 0; + readLock.lock(); try { ensureOpen(); if (!isBlocking()) throw new IllegalBlockingModeException(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - boolean connected = isConnected(); - SocketAddress sender; - do { - if (nanos > 0) { - sender = trustedBlockingReceive(dst, nanos); - } else { - sender = trustedBlockingReceive(dst); - } - // check sender when security manager set and not connected - if (sm != null && !connected) { - InetSocketAddress isa = (InetSocketAddress) sender; - try { - sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort()); - } catch (SecurityException e) { - sender = null; - } - } - } while (sender == null); - return sender; - } finally { - readLock.unlock(); - } - } - /** - * Receives a datagram into given buffer. This method is used to support - * the socket adaptor. The buffer is assumed to be trusted. - * @throws SocketTimeoutException if the timeout elapses - */ - private SocketAddress trustedBlockingReceive(ByteBuffer dst) - throws IOException - { - assert readLock.isHeldByCurrentThread() && isBlocking(); - SocketAddress sender = null; - try { - SocketAddress remote = beginRead(true, false); - configureSocketNonBlockingIfVirtualThread(); - boolean connected = (remote != null); - int n = receive(dst, connected); - while (IOStatus.okayToRetry(n) && isOpen()) { - park(Net.POLLIN); - n = receive(dst, connected); + // underlying socket needs to be non-blocking if timed receive or virtual thread + if (nanos > 0) { + configureSocketNonBlocking(); + } else { + configureSocketNonBlockingIfVirtualThread(); + nanos = Long.MAX_VALUE; + } + + // p.bufLength is the maximum size of the datagram that can be received + int bufLength; + synchronized (p) { + bufLength = DatagramPackets.getBufLength(p); } - if (n > 0 || (n == 0 && isOpen())) { - // sender address is in socket address buffer - sender = sourceSocketAddress(); + + long startNanos = System.nanoTime(); + SocketAddress sender = null; + try { + SocketAddress remote = beginRead(true, false); + boolean connected = (remote != null); + do { + long remainingNanos = nanos - (System.nanoTime() - startNanos); + ByteBuffer dst = tryBlockingReceive(connected, bufLength, remainingNanos); + + // if datagram received then get sender and copy to DatagramPacket + if (dst != null) { + try { + // sender address is in socket address buffer + sender = sourceSocketAddress(); + + // check sender when security manager set and not connected + @SuppressWarnings("removal") + SecurityManager sm = System.getSecurityManager(); + if (sm != null && !connected) { + InetSocketAddress isa = (InetSocketAddress) sender; + try { + sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort()); + } catch (SecurityException e) { + sender = null; + } + } + + // copy bytes to the DatagramPacket, and set length and sender + if (sender != null) { + synchronized (p) { + // re-read p.bufLength in case DatagramPacket changed + int len = Math.min(dst.limit(), DatagramPackets.getBufLength(p)); + dst.get(p.getData(), p.getOffset(), len); + DatagramPackets.setLength(p, len); + p.setSocketAddress(sender); + } + } + } finally { + Util.offerFirstTemporaryDirectBuffer(dst); + } + } + } while (sender == null && isOpen()); + } finally { + endRead(true, (sender != null)); } - return sender; } finally { - endRead(true, (sender != null)); + readLock.unlock(); } } /** - * Receives a datagram into given buffer with a timeout. This method is - * used to support the socket adaptor. The buffer is assumed to be trusted. + * Attempt to receive a datagram. + * + * @param connected if the channel's socket is connected + * @param len the maximum size of the datagram to receive + * @param nanos the timeout, should be Long.MAX_VALUE for untimed + * @return a direct buffer containing the datagram or null if channel is closed * @throws SocketTimeoutException if the timeout elapses */ - private SocketAddress trustedBlockingReceive(ByteBuffer dst, long nanos) + private ByteBuffer tryBlockingReceive(boolean connected, int len, long nanos) throws IOException { - assert readLock.isHeldByCurrentThread() && isBlocking(); - SocketAddress sender = null; - try { - SocketAddress remote = beginRead(true, false); - boolean connected = (remote != null); - - // change socket to non-blocking - lockedConfigureBlocking(false); - try { - long startNanos = System.nanoTime(); - int n = receive(dst, connected); - while (n == IOStatus.UNAVAILABLE && isOpen()) { - long remainingNanos = nanos - (System.nanoTime() - startNanos); - if (remainingNanos <= 0) { - throw new SocketTimeoutException("Receive timed out"); - } - park(Net.POLLIN, remainingNanos); - n = receive(dst, connected); - } - if (n > 0 || (n == 0 && isOpen())) { - // sender address is in socket address buffer - sender = sourceSocketAddress(); + long startNanos = System.nanoTime(); + ByteBuffer dst = Util.getTemporaryDirectBuffer(len); + int n = -1; + try { + n = receive(dst, connected); + while (n == IOStatus.UNAVAILABLE && isOpen()) { + // virtual thread needs to release temporary direct buffer before parking + if (Thread.currentThread().isVirtual()) { + Util.offerFirstTemporaryDirectBuffer(dst); + dst = null; + } + long remainingNanos = nanos - (System.nanoTime() - startNanos); + if (remainingNanos <= 0) { + throw new SocketTimeoutException("Receive timed out"); + } + park(Net.POLLIN, remainingNanos); + // virtual thread needs to re-allocate temporary direct buffer after parking + if (Thread.currentThread().isVirtual()) { + dst = Util.getTemporaryDirectBuffer(len); } - return sender; - } finally { - // restore socket to blocking mode (if channel is open) - tryLockedConfigureBlocking(true); + n = receive(dst, connected); } + dst.flip(); } finally { - endRead(true, (sender != null)); + // release buffer if no datagram received + if (dst != null && (n < 0 || (n == 0 && !isOpen()))) { + Util.offerFirstTemporaryDirectBuffer(dst); + dst = null; + } } + return dst; } /** @@ -889,19 +906,54 @@ } /** - * Sends a datagram from the bytes in given buffer. + * Sends a datagram. * * @apiNote This method is for use by the socket adaptor. * + * @throws IllegalArgumentException if not connected and target address not set * @throws IllegalBlockingModeException if the channel is non-blocking */ - void blockingSend(ByteBuffer src, SocketAddress target) throws IOException { + void blockingSend(DatagramPacket p) throws IOException { + Objects.requireNonNull(p); + writeLock.lock(); try { ensureOpen(); if (!isBlocking()) throw new IllegalBlockingModeException(); - send(src, target); + + ByteBuffer src = null; + try { + InetSocketAddress target; + synchronized (p) { + int len = p.getLength(); + src = Util.getTemporaryDirectBuffer(len); + + // copy bytes to temporary direct buffer + src.put(p.getData(), p.getOffset(), len); + src.flip(); + + // target address + if (p.getAddress() == null) { + InetSocketAddress remote = remoteAddress(); + if (remote == null) { + throw new IllegalArgumentException("Address not set"); + } + // set address/port to be compatible with long standing behavior + p.setAddress(remote.getAddress()); + p.setPort(remote.getPort()); + target = remote; + } else { + target = (InetSocketAddress) p.getSocketAddress(); + } + } + + // send the datagram (does not block) + send(src, target); + + } finally { + if (src != null) Util.offerFirstTemporaryDirectBuffer(src); + } } finally { writeLock.unlock(); } @@ -1198,12 +1250,12 @@ } /** - * Ensures that the socket is configured non-blocking when on a virtual thread. + * Ensures that the socket is configured non-blocking. * @throws IOException if there is an I/O error changing the blocking mode */ - private void configureSocketNonBlockingIfVirtualThread() throws IOException { + private void configureSocketNonBlocking() throws IOException { assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread(); - if (!forcedNonBlocking && Thread.currentThread().isVirtual()) { + if (!forcedNonBlocking) { synchronized (stateLock) { ensureOpen(); IOUtil.configureBlocking(fd, false); @@ -1212,6 +1264,16 @@ } } + /** + * Ensures that the socket is configured non-blocking when on a virtual thread. + * @throws IOException if there is an I/O error changing the blocking mode + */ + private void configureSocketNonBlockingIfVirtualThread() throws IOException { + if (Thread.currentThread().isVirtual()) { + configureSocketNonBlocking(); + } + } + InetSocketAddress localAddress() { synchronized (stateLock) { return localAddress; @@ -1952,6 +2014,44 @@ }; } + /** + * Defines static methods to get/set DatagramPacket fields and workaround + * DatagramPacket deficiencies. + */ + private static class DatagramPackets { + private static final VarHandle LENGTH; + private static final VarHandle BUF_LENGTH; + static { + try { + PrivilegedExceptionAction pa = () -> + MethodHandles.privateLookupIn(DatagramPacket.class, MethodHandles.lookup()); + @SuppressWarnings("removal") + MethodHandles.Lookup l = AccessController.doPrivileged(pa); + LENGTH = l.findVarHandle(DatagramPacket.class, "length", int.class); + BUF_LENGTH = l.findVarHandle(DatagramPacket.class, "bufLength", int.class); + } catch (Exception e) { + throw new ExceptionInInitializerError(e); + } + } + + /** + * Sets the DatagramPacket.length field. DatagramPacket.setLength cannot be + * used at this time because it sets both the length and bufLength fields. + */ + static void setLength(DatagramPacket p, int value) { + assert Thread.holdsLock(p); + LENGTH.set(p, value); + } + + /** + * Returns the value of the DatagramPacket.bufLength field. + */ + static int getBufLength(DatagramPacket p) { + assert Thread.holdsLock(p); + return (int) BUF_LENGTH.get(p); + } + } + // -- Native methods -- private static native void disconnect0(FileDescriptor fd, boolean isIPv6) diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -32,7 +32,6 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; -import java.lang.invoke.VarHandle; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; @@ -44,7 +43,6 @@ import java.net.SocketOption; import java.net.SocketTimeoutException; import java.net.StandardSocketOptions; -import java.nio.ByteBuffer; import java.nio.channels.AlreadyConnectedException; import java.nio.channels.ClosedChannelException; import java.nio.channels.ClosedByInterruptException; @@ -56,7 +54,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; -import jdk.internal.misc.Blocker; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -192,79 +189,30 @@ @Override public void send(DatagramPacket p) throws IOException { - synchronized (p) { - int len = p.getLength(); - ByteBuffer bb = Util.getTemporaryDirectBuffer(len); - try { - // copy bytes to temporary direct buffer - bb.put(p.getData(), p.getOffset(), len); - bb.flip(); - - // target address - InetSocketAddress target; - if (p.getAddress() == null) { - InetSocketAddress remote = dc.remoteAddress(); - if (remote == null) { - // not specified by DatagramSocket - throw new IllegalArgumentException("Address not set"); - } - // set address/port to maintain compatibility with DatagramSocket - p.setAddress(remote.getAddress()); - p.setPort(remote.getPort()); - target = remote; - } else { - target = (InetSocketAddress) p.getSocketAddress(); - } - - // send datagram - dc.blockingSend(bb, target); - } catch (AlreadyConnectedException e) { - throw new IllegalArgumentException("Connected and packet address differ"); - } catch (ClosedChannelException e) { - throw new SocketException("Socket closed", e); - } finally { - Util.offerFirstTemporaryDirectBuffer(bb); - } + try { + dc.blockingSend(p); + } catch (AlreadyConnectedException e) { + throw new IllegalArgumentException("Connected and packet address differ"); + } catch (ClosedChannelException e) { + throw new SocketException("Socket closed", e); } } @Override public void receive(DatagramPacket p) throws IOException { - synchronized (p) { - // get temporary direct buffer with a capacity of p.bufLength - int bufLength = DatagramPackets.getBufLength(p); - ByteBuffer bb = Util.getTemporaryDirectBuffer(bufLength); - try { - SocketAddress sender; - long comp = Blocker.begin(); - try { - sender = dc.blockingReceive(bb, MILLISECONDS.toNanos(timeout)); - } finally { - Blocker.end(comp); - } - bb.flip(); - - // copy bytes to the DatagramPacket and set length - int len = Math.min(bb.limit(), DatagramPackets.getBufLength(p)); - bb.get(p.getData(), p.getOffset(), len); - DatagramPackets.setLength(p, len); - - // sender address - p.setSocketAddress(sender); - } catch (SocketTimeoutException | ClosedByInterruptException e) { - throw e; - } catch (InterruptedIOException e) { - Thread thread = Thread.currentThread(); - if (thread.isVirtual() && thread.isInterrupted()) { - close(); - throw new SocketException("Closed by interrupt"); - } - throw e; - } catch (ClosedChannelException e) { - throw new SocketException("Socket closed", e); - } finally { - Util.offerFirstTemporaryDirectBuffer(bb); + try { + dc.blockingReceive(p, MILLISECONDS.toNanos(timeout)); + } catch (SocketTimeoutException | ClosedByInterruptException e) { + throw e; + } catch (InterruptedIOException e) { + Thread thread = Thread.currentThread(); + if (thread.isVirtual() && thread.isInterrupted()) { + close(); + throw new SocketException("Closed by interrupt"); } + throw e; + } catch (ClosedChannelException e) { + throw new SocketException("Socket closed", e); } } @@ -705,44 +653,6 @@ } /** - * Defines static methods to get/set DatagramPacket fields and workaround - * DatagramPacket deficiencies. - */ - private static class DatagramPackets { - private static final VarHandle LENGTH; - private static final VarHandle BUF_LENGTH; - static { - try { - PrivilegedExceptionAction pa = () -> - MethodHandles.privateLookupIn(DatagramPacket.class, MethodHandles.lookup()); - @SuppressWarnings("removal") - MethodHandles.Lookup l = AccessController.doPrivileged(pa); - LENGTH = l.findVarHandle(DatagramPacket.class, "length", int.class); - BUF_LENGTH = l.findVarHandle(DatagramPacket.class, "bufLength", int.class); - } catch (Exception e) { - throw new ExceptionInInitializerError(e); - } - } - - /** - * Sets the DatagramPacket.length field. DatagramPacket.setLength cannot be - * used at this time because it sets both the length and bufLength fields. - */ - static void setLength(DatagramPacket p, int value) { - assert Thread.holdsLock(p); - LENGTH.set(p, value); - } - - /** - * Returns the value of the DatagramPacket.bufLength field. - */ - static int getBufLength(DatagramPacket p) { - assert Thread.holdsLock(p); - return (int) BUF_LENGTH.get(p); - } - } - - /** * Defines static methods to invoke non-public NetworkInterface methods. */ private static class NetworkInterfaces { diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java 2024-01-16 16:19:00.000000000 +0000 @@ -1041,10 +1041,10 @@ // -- Memory-mapped buffers -- - private abstract static class Unmapper + private sealed abstract static class Unmapper implements Runnable, UnmapperProxy { - private volatile long address; + private final long address; protected final long size; protected final long cap; private final FileDescriptor fd; @@ -1081,10 +1081,7 @@ } public void unmap() { - if (address == 0) - return; nd.unmap(address, size); - address = 0; // if this mapping has a valid file descriptor then we close it if (fd.valid()) { @@ -1101,7 +1098,7 @@ protected abstract void decrementStats(); } - private static class DefaultUnmapper extends Unmapper { + private static final class DefaultUnmapper extends Unmapper { // keep track of non-sync mapped buffer usage static volatile int count; @@ -1134,7 +1131,7 @@ } } - private static class SyncUnmapper extends Unmapper { + private static final class SyncUnmapper extends Unmapper { // keep track of mapped buffer usage static volatile int count; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java 2024-01-16 16:19:00.000000000 +0000 @@ -41,6 +41,7 @@ import java.util.*; import javax.security.auth.x500.X500Principal; +import jdk.internal.misc.ThreadTracker; import sun.security.provider.certpath.PKIX.BuilderParams; import sun.security.util.Debug; import sun.security.x509.AccessDescription; @@ -71,6 +72,10 @@ TrustAnchor trustAnchor; private final boolean searchAllCertStores; + private static class ThreadTrackerHolder { + static final ThreadTracker AIA_TRACKER = new ThreadTracker(); + } + /** * Initialize the builder with the input parameters. * @@ -336,7 +341,7 @@ } /** - * Download Certificates from the given AIA and add them to the + * Download certificates from the given AIA and add them to the * specified Collection. */ // cs.getCertificates(caSelector) returns a collection of X509Certificate's @@ -348,32 +353,47 @@ if (!Builder.USE_AIA) { return false; } + List adList = aiaExt.getAccessDescriptions(); if (adList == null || adList.isEmpty()) { return false; } - boolean add = false; - for (AccessDescription ad : adList) { - CertStore cs = URICertStore.getInstance(ad); - if (cs != null) { - try { - if (certs.addAll((Collection) - cs.getCertificates(caSelector))) { - add = true; - if (!searchAllCertStores) { - return true; + Object key = ThreadTrackerHolder.AIA_TRACKER.tryBegin(); + if (key == null) { + // Avoid recursive fetching of certificates + if (debug != null) { + debug.println("Recursive fetching of certs via the AIA " + + "extension detected"); + } + return false; + } + + try { + boolean add = false; + for (AccessDescription ad : adList) { + CertStore cs = URICertStore.getInstance(ad); + if (cs != null) { + try { + if (certs.addAll((Collection) + cs.getCertificates(caSelector))) { + add = true; + if (!searchAllCertStores) { + return true; + } + } + } catch (CertStoreException cse) { + if (debug != null) { + debug.println("exception getting certs from CertStore:"); + cse.printStackTrace(); } - } - } catch (CertStoreException cse) { - if (debug != null) { - debug.println("exception getting certs from CertStore:"); - cse.printStackTrace(); } } } + return add; + } finally { + ThreadTrackerHolder.AIA_TRACKER.end(key); } - return add; } /** diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/rsa/RSASignature.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/rsa/RSASignature.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/rsa/RSASignature.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/rsa/RSASignature.java 2024-01-16 16:19:00.000000000 +0000 @@ -217,8 +217,17 @@ byte[] decrypted = RSACore.rsa(sigBytes, publicKey); byte[] digest = getDigestValue(); + byte[] encoded = RSAUtil.encodeSignature(digestOID, digest); byte[] padded = padding.pad(encoded); + if (MessageDigest.isEqual(padded, decrypted)) { + return true; + } + + // Some vendors might omit the NULL params in digest algorithm + // identifier. Try again. + encoded = RSAUtil.encodeSignatureWithoutNULL(digestOID, digest); + padded = padding.pad(encoded); return MessageDigest.isEqual(padded, decrypted); } catch (javax.crypto.BadPaddingException e) { return false; diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/rsa/RSAUtil.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/rsa/RSAUtil.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/rsa/RSAUtil.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/rsa/RSAUtil.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -180,28 +180,15 @@ } /** - * Decode the signature data. Verify that the object identifier matches - * and return the message digest. + * Encode the digest without the NULL params, return the to-be-signed data. + * This is only used by SunRsaSign. */ - public static byte[] decodeSignature(ObjectIdentifier oid, byte[] sig) - throws IOException { - // Enforce strict DER checking for signatures - DerInputStream in = new DerInputStream(sig, 0, sig.length, false); - DerValue[] values = in.getSequence(2); - if ((values.length != 2) || (in.available() != 0)) { - throw new IOException("SEQUENCE length error"); - } - AlgorithmId algId = AlgorithmId.parse(values[0]); - if (!algId.getOID().equals(oid)) { - throw new IOException("ObjectIdentifier mismatch: " - + algId.getOID()); - } - if (algId.getEncodedParams() != null) { - throw new IOException("Unexpected AlgorithmId parameters"); - } - if (values[1].isConstructed()) { - throw new IOException("Unexpected constructed digest value"); - } - return values[1].getOctetString(); + static byte[] encodeSignatureWithoutNULL(ObjectIdentifier oid, byte[] digest) { + DerOutputStream out = new DerOutputStream(); + out.write(DerValue.tag_Sequence, new DerOutputStream().putOID(oid)); + out.putOctetString(digest); + DerValue result = + new DerValue(DerValue.tag_Sequence, out.toByteArray()); + return result.toByteArray(); } } diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java 2024-01-16 16:19:00.000000000 +0000 @@ -128,7 +128,7 @@ ArrayList keyTypes = new ArrayList<>(3); for (byte id : ids) { ClientCertificateType cct = ClientCertificateType.valueOf(id); - if (cct.isAvailable) { + if (cct != null && cct.isAvailable) { cct.keyAlgorithm.forEach(key -> { if (!keyTypes.contains(key)) { keyTypes.add(key); diff -Nru openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/util/KeyUtil.java openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/util/KeyUtil.java --- openjdk-21-21.0.1+12/src/java.base/share/classes/sun/security/util/KeyUtil.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/classes/sun/security/util/KeyUtil.java 2024-01-16 16:19:00.000000000 +0000 @@ -293,13 +293,14 @@ * contains the lower of that suggested by the client in the client * hello and the highest supported by the server. * @param encoded the encoded key in its "RAW" encoding format - * @param isFailOver whether the previous decryption of the - * encrypted PreMasterSecret message run into problem + * @param failure true if encoded is incorrect according to previous checks * @return the polished PreMasterSecret key in its "RAW" encoding format */ public static byte[] checkTlsPreMasterSecretKey( int clientVersion, int serverVersion, SecureRandom random, - byte[] encoded, boolean isFailOver) { + byte[] encoded, boolean failure) { + + byte[] tmp; if (random == null) { random = JCAUtil.getSecureRandom(); @@ -307,30 +308,38 @@ byte[] replacer = new byte[48]; random.nextBytes(replacer); - if (!isFailOver && (encoded != null)) { - // check the length - if (encoded.length != 48) { - // private, don't need to clone the byte array. - return replacer; - } - - int encodedVersion = - ((encoded[0] & 0xFF) << 8) | (encoded[1] & 0xFF); - if (clientVersion != encodedVersion) { - if (clientVersion > 0x0301 || // 0x0301: TLSv1 - serverVersion != encodedVersion) { - encoded = replacer; - } // Otherwise, For compatibility, we maintain the behavior - // that the version in pre_master_secret can be the - // negotiated version for TLS v1.0 and SSL v3.0. - } + if (failure) { + tmp = replacer; + } else { + tmp = encoded; + } + if (tmp == null) { + encoded = replacer; + } else { + encoded = tmp; + } + // check the length + if (encoded.length != 48) { // private, don't need to clone the byte array. - return encoded; + tmp = replacer; + } else { + tmp = encoded; } - // private, don't need to clone the byte array. - return replacer; + int encodedVersion = + ((tmp[0] & 0xFF) << 8) | (tmp[1] & 0xFF); + int check1 = 0; + int check2 = 0; + int check3 = 0; + if (clientVersion != encodedVersion) check1 = 1; + if (clientVersion > 0x0301) check2 = 1; + if (serverVersion != encodedVersion) check3 = 1; + if ((check1 & (check2 | check3)) == 1) { + return replacer; + } else { + return tmp; + } } /** diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicertcseccrootg5 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicertcseccrootg5 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicertcseccrootg5 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicertcseccrootg5 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,21 @@ +Owner: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Serial number: 3698fe712d519f3ced0fdb7b1643011 +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICFjCCAZ2gAwIBAgIQA2mP5xLVGfPO0P23sWQwETAKBggqhkjOPQQDAzBNMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERp +Z2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYw +MTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu +Yy4xJTAjBgNVBAMTHERpZ2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAR/FK2Ftpf9AiE1TWDoOJOTmz0FEG2v0/7v+rv7c5nz +7DISjcdouIveiaKIVHeNuyF+M5VWlgno1YyhBLibbhkAYuhCKKZYN4QZVSZ7Mzdn +8ppyraGurgBCPBx+uHqeIZyjQjBAMB0GA1UdDgQWBBTwjJhxOThlwjobphdmHcjt +Zd6SNjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQD +AwNnADBkAjAjb+EAGSZQ5EYgZYs3p8/rBuHMMskqoewyDXOiHgIcNWEqTmmrOXft +l4jAfWvqid0CMEPx0VijdT6Gm7ZVEYsX9z3+CmnFf07GdRtalMvqERHGCCKI3tB6 +oqV56OMhp80Tsw== +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicertcsrsarootg5 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicertcsrsarootg5 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicertcsrsarootg5 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicertcsrsarootg5 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,38 @@ +Owner: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Serial number: 6cee131be6d55c807f7c0c7fb44e620 +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQBs7hMb5tVcgH98DH+0TmIDANBgkqhkiG9w0BAQwFADBM +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJDAiBgNVBAMT +G0RpZ2lDZXJ0IENTIFJTQTQwOTYgUm9vdCBHNTAeFw0yMTAxMTUwMDAwMDBaFw00 +NjAxMTQyMzU5NTlaMEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg +SW5jLjEkMCIGA1UEAxMbRGlnaUNlcnQgQ1MgUlNBNDA5NiBSb290IEc1MIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtjNzgNhiA3AULBEcOV58rnyDhh3+ +Ji9MJK2L6oNfqbw9W/wLmEwCRzDs4v7s6DRbZl6/O9cspiX/jFmz3+rafCnZRlBy +CB1u0RsK3R/NmYn6Dw9zxOGcHXUyzW+X2ipqlbJsyQnQ6gt7fRcGSZnv1t7gyFPU +rsZ38Ya7Ixy4wN9Z94590e+C5iaLWji1/3XVstlPCfM3iFDaEaSKFBTRUwQAffNq +RBj+UHAyBxyomg46HcUKH24LJmm3PKJXcCyG+kxulalYQ7msEtb/P+3XQxdrTM6e +xJCr//oQUJqjkFfW54wQrp8WGs81HX/Xdu2KnDWnKLinXSH8MDfd3ggZTxXG56ba +kEeO95RTTI5TAr79meXqhtCvAwLTm6qT8asojiAB/0z7zLcpQPWHpBITBR9DbtdR +UJ84tCDtFwkSj8y5Ga+fzb5pEdOvVRBtF4Z5llLGsgCd5a84sDX0iGuPDgQ9fO6v +zdNqEErGzYbKIj2hSlz7Dv+I31xip8C5HtmsbH44N/53kyXChYpPtTcGWgaBFPHO +lJ2ZkeoyWs5nPW4EZq0MTy2jLvee9Xid9wr9fo/jQopVlrzxnzct/J5flf6MGBv8 +jv1LkK/XA2gSY6zik6eiywTlT2TOA/rGFJ/Zi+jM1GKMa+QALBmfGgbGMYFU+1Mk +mq9Vmbqdda64wt0CAwEAAaNCMEAwHQYDVR0OBBYEFGgBk7HSSkBCaZRGLBxaiKkl +tEdPMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +DAUAA4ICAQCS/O64AnkXAlF9IcVJZ6ek8agkOOsMaOpaQmuc9HPBaUotszcFUEKY +kp4GeSwuBpn2798roM2zkgGDtaDLJ7U8IxqYSaLsLZmlWUOs0rGT1lfXHLyT1sZA +4bNvGVW3E9flQzOktavL2sExZA101iztw41u67uvGUdhYS3A9AW5b3jcOvdCQGVT +kb2ZDZOSVKapN1krm8uZxrw99wSE8JQzHQ+CWjnLLkXDKBmjspuYyPwxa2CP9umG +KLzgPH10XRaJW2kkxxCLxEu7Nk/UWT/DsKSRmfgu0UoBnfWIEu+/WhFqWU9Za1pn +84+0Ew/A2C89KHKqGX8RfWpbn5XnX7eUT/E+oVr/Lcyd3yd3jzJzHGcKdvP6XLG/ +vB29DCibsscXZwszD8O9Ntz7ukILq+2Ew2LWhBapsQdrqW7uxs/msEQpwvCzYYAq +i2/SFFwlh1Rk86RMwaH4p2vq/uo6/HnbDo/cxvPJ1Gze6YOhjh0i7Mk6sgB73Dun +Qhp/3IupET2Op8Agb10JXUNE5o9mzKlbB/Hvm3oOs1ThlP0OLMaT11X9cZg1uAlK +/8YpKCz2Ui3bFBiSJ+IWfozK1GG+goeR65g3P79fXXc/NKwbOEOraHKZMh46Ghml +ozhMI9ej58zVKpIXkAtaS70WvfuGauKJmezkoFUYyaMIHxPgMghy0A== +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicerttlseccrootg5 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicerttlseccrootg5 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicerttlseccrootg5 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicerttlseccrootg5 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,21 @@ +Owner: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Serial number: 9e09365acf7d9c8b93e1c0b042a2ef3 +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicerttlsrsarootg5 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicerttlsrsarootg5 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/digicerttlsrsarootg5 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/digicerttlsrsarootg5 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,38 @@ +Owner: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Serial number: 8f9b478a8fa7eda6a333789de7ccf8a +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/emsigneccrootcag3 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/emsigneccrootcag3 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/emsigneccrootcag3 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/emsigneccrootcag3 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,22 @@ +Owner: CN=emSign ECC Root CA - G3, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN +Issuer: CN=emSign ECC Root CA - G3, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN +Serial number: 3cf607a968700eda8b84 +Valid from: Sun Feb 18 18:30:00 GMT 2018 until: Wed Feb 18 18:30:00 GMT 2043 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/emsignrootcag1 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/emsignrootcag1 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/emsignrootcag1 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/emsignrootcag1 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,29 @@ +Owner: CN=emSign Root CA - G1, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN +Issuer: CN=emSign Root CA - G1, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN +Serial number: 31f5e4620c6c58edd6d8 +Valid from: Sun Feb 18 18:30:00 GMT 2018 until: Wed Feb 18 18:30:00 GMT 2043 +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/emsignrootcag2 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/emsignrootcag2 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/emsignrootcag2 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/emsignrootcag2 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,39 @@ +Owner: CN=emSign Root CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN +Issuer: CN=emSign Root CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN +Serial number: 864dbf0fe35ed77d8ed8 +Valid from: Sun Feb 18 18:30:00 GMT 2018 until: Wed Feb 18 18:30:00 GMT 2043 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFlTCCA32gAwIBAgILAIZNvw/jXtd9jtgwDQYJKoZIhvcNAQEMBQAwZzELMAkG +A1UEBhMCSU4xEzARBgNVBAsTCmVtU2lnbiBQS0kxJTAjBgNVBAoTHGVNdWRocmEg +VGVjaG5vbG9naWVzIExpbWl0ZWQxHDAaBgNVBAMTE2VtU2lnbiBSb290IENBIC0g +RzIwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBnMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMjCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMNwGIWW2kHfHK+sXTNwxF07K+IV +ySTuyFM2r1v002wUfcdT+zs5OM5QbMYFFnedXQI6gCFLsjKrcaej48Zt37OyEb3i +aPs7CsP4kAyTwzKH9aZe6gXYHrJq40/ZVMNcQVI2PcIp40B/SAN2gUZ+ZaUtIOvV +jEx26/ebNaXRIsthlkOG/caB+QRwDw1tl7338Zlv0M2oTBUy4B3e7dGP5pgXH71M +jqHPCoNo+xv9f0NTBT+hUDa8h8wUtcGQq9CDeJTpjWcD2bP2AMdVG6oVpMAUeUzo +cCyglvtFdUMjggxBbw4qhau1HXPG8Ot9hwL7ZMi8tkTzrvUIxxb8G9LF/7kKeCE7 +tGZaVzDTnXuifl3msR4ErHsQ4P7lVu2AIjIAhrAXoedDidb7pMcf7TABdrYUT1Jo +G/AiK+J9jO6GTjeADD4LMDSBZhHMuBK/PJ/g0kGBt+/C1L+/HURzQhJkMlRnM6Rv +XoCtfKopSlns5trZmTi971Wjbn88QXP61lGpBCUPwCjs7rpOYvSUJtI+lcbF+37q +kIqOXYkVT3cupDSpw+H89kFtj5GKY+Xny4LxY+3IvDIRiyd6ky1DPj713DI0yqve +EpsIr3A0PdwuyUI7CS1jg0NnGFT6Xxyr0xB+VDt83FJYW8v16k2pbaQ4kVxA3aXd +X9dZYyVR1S59KM75AgMBAAGjQjBAMB0GA1UdDgQWBBTt7E1FYRgo57MjKBEcTaUn +DV7s9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B +AQwFAAOCAgEACFC/ilQg8KTCVBxFJW/sazomkS0kNYbEIZg4B3obqwsJ7SX98z8Z +gfzBpz0nYClwwJjWbFN1R2zY8pCEot6/dgmA8Vbq0GxhwPM5YN/SZquNyRIxO3cU +dlAcwf+vSezdVCf9wOzvSAF3q0a5ljvbdbNJNpfScQVp7UUd5sBsZk8jXO1KQ/go +/Vf/GDPnrIFmxpAIGE3sgnO8lAv9FzUaAeuv7HWe47xN9J7+bQzF93yHuIXACPTL +pQHhg2zMv5C7BAbuDHfbj1Cu294Z832yhSfBcziWGskOvl3es2EcHytbS9c9P+0z +Mpka7zGC1FHrvLb/FoduH86TeZt0QjZ6pcplNzoaxDnDvzTJ6CC2Eny+qH/APFCu +VUv5/wjwF+HPm8Pup2ARj9cEp92+0qcerfHacNq5hMeGZdbA/dzdUR/5z5zXdxAk +nl8mcfGb0eMNSTXQmmB/i4AecNnr72uYjzlaXUGYN7Nrb6XouG0pnh0/BBtWWp0U +ShIPpWEAqs7RJBj6+1ZUYXZ4ObrCw962DxhN2p19Hxw9LtuUUcLqqTPrFXYvwO4t +ouj7KJnAkaTUfXGdEaFVtFig1EA30WzJY2X1vAQ7hVnniCjgaXAGqjsU6sklNM9n +xDx5rFCCCEtj9Kh8UHjGK2QqgP5kwgttjOApQMaCoezMfK4KD7WpOXU= +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/letsencryptisrgx2 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/letsencryptisrgx2 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/letsencryptisrgx2 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/letsencryptisrgx2 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,21 @@ +Owner: CN=ISRG Root X2, O=Internet Security Research Group, C=US +Issuer: CN=ISRG Root X2, O=Internet Security Research Group, C=US +Serial number: 41d29dd172eaeea780c12c6ce92f8752 +Valid from: Fri Sep 04 00:00:00 GMT 2020 until: Mon Sep 17 16:00:00 GMT 2040 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/teliarootcav2 openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/teliarootcav2 --- openjdk-21-21.0.1+12/src/java.base/share/data/cacerts/teliarootcav2 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/data/cacerts/teliarootcav2 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,39 @@ +Owner: CN=Telia Root CA v2, O=Telia Finland Oyj, C=FI +Issuer: CN=Telia Root CA v2, O=Telia Finland Oyj, C=FI +Serial number: 1675f27d6fe7ae3e4acbe095b059e +Valid from: Thu Nov 29 11:55:54 GMT 2018 until: Sun Nov 29 11:55:54 GMT 2043 +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- diff -Nru openjdk-21-21.0.1+12/src/java.base/share/native/libverify/check_code.c openjdk-21-21.0.2+13/src/java.base/share/native/libverify/check_code.c --- openjdk-21-21.0.1+12/src/java.base/share/native/libverify/check_code.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/share/native/libverify/check_code.c 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -81,6 +81,7 @@ #include #include #include +#include #include "jni.h" #include "jni_util.h" @@ -1195,7 +1196,7 @@ } } if (opcode == JVM_OPC_tableswitch) { - keys = _ck_ntohl(lpc[2]) - _ck_ntohl(lpc[1]) + 1; + keys = _ck_ntohl(lpc[2]) - _ck_ntohl(lpc[1]) + 1; delta = 1; } else { keys = _ck_ntohl(lpc[1]); /* number of pairs */ @@ -1677,11 +1678,14 @@ switch (instruction) { case JVM_OPC_tableswitch: { int *lpc = (int *)UCALIGN(iptr + 1); - int index; + int64_t low, high, index; if (lpc + 2 >= (int *)end) { return -1; /* do not read pass the end */ } - index = _ck_ntohl(lpc[2]) - _ck_ntohl(lpc[1]); + low = _ck_ntohl(lpc[1]); + high = _ck_ntohl(lpc[2]); + index = high - low; + // The value of low must be less than or equal to high - i.e. index >= 0 if ((index < 0) || (index > 65535)) { return -1; /* illegal */ } else { diff -Nru openjdk-21-21.0.1+12/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java openjdk-21-21.0.2+13/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java --- openjdk-21-21.0.1+12/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, 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 @@ -25,10 +25,15 @@ package sun.nio.fs; -import java.nio.file.attribute.*; -import java.util.concurrent.TimeUnit; -import java.util.Set; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.nio.file.attribute.GroupPrincipal; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.TimeUnit; /** * Unix implementation of PosixFileAttributes. @@ -52,6 +57,7 @@ private long st_ctime_sec; private long st_ctime_nsec; private long st_birthtime_sec; + private long st_birthtime_nsec; // created lazily private volatile UserPrincipal owner; @@ -158,7 +164,7 @@ @Override public FileTime creationTime() { if (UnixNativeDispatcher.birthtimeSupported()) { - return FileTime.from(st_birthtime_sec, TimeUnit.SECONDS); + return toFileTime(st_birthtime_sec, st_birthtime_nsec); } else { // return last modified when birth time not supported return lastModifiedTime(); diff -Nru openjdk-21-21.0.1+12/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c openjdk-21-21.0.2+13/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c --- openjdk-21-21.0.1+12/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c 2024-01-16 16:19:00.000000000 +0000 @@ -485,18 +485,28 @@ } /* - * The following functions are common on Solaris, Linux and AIX. + * The following functions are for Linux */ -#if defined (__linux__) || defined(_AIX) +#if defined (__linux__) /* - * Returns the children of the requested pid and optionally each parent and - * start time. - * Reads /proc and accumulates any process who parent pid matches. - * The resulting pids are stored into the array of longs. + * Return pids of active processes, and optionally parent pids and + * start times for each process. + * For a specific non-zero pid, only the direct children are returned. + * If the pid is zero, all active processes are returned. + * Reads /proc and accumulates any process following the rules above. + * The resulting pids are stored into an array of longs named jarray. * The number of pids is returned if they all fit. - * If the array is too short, the negative of the desired length is returned. + * If the parentArray is non-null, store also the parent pid. + * In this case the parentArray must have the same length as the result pid array. + * Of course in the case of a given non-zero pid all entries in the parentArray + * will contain this pid, so this array does only make sense in the case of a given + * zero pid. + * If the jstimesArray is non-null, store also the start time of the pid. + * In this case the jstimesArray must have the same length as the result pid array. + * If the array(s) (is|are) too short, excess pids are not stored and + * the desired length is returned. */ jint unix_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, jlongArray jparentArray, jlongArray jstimesArray) { @@ -607,7 +617,7 @@ return count; } -#endif // defined (__linux__) || defined(_AIX) +#endif // defined (__linux__) /* * The following functions are for AIX. diff -Nru openjdk-21-21.0.1+12/src/java.base/unix/native/libjava/java_props_md.c openjdk-21-21.0.2+13/src/java.base/unix/native/libjava/java_props_md.c --- openjdk-21-21.0.1+12/src/java.base/unix/native/libjava/java_props_md.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/unix/native/libjava/java_props_md.c 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -238,6 +238,11 @@ *std_language = "en"; if (language != NULL && mapLookup(language_names, language, std_language) == 0) { *std_language = malloc(strlen(language)+1); + if (*std_language == NULL) { + free(encoding_variant); + JNU_ThrowOutOfMemoryError(env, NULL); + return 0; + } strcpy(*std_language, language); } } @@ -246,6 +251,11 @@ if (std_country != NULL && country != NULL) { if (mapLookup(country_names, country, std_country) == 0) { *std_country = malloc(strlen(country)+1); + if (*std_country == NULL) { + free(encoding_variant); + JNU_ThrowOutOfMemoryError(env, NULL); + return 0; + } strcpy(*std_country, country); } } diff -Nru openjdk-21-21.0.1+12/src/java.base/unix/native/libnio/ch/UnixFileDispatcherImpl.c openjdk-21-21.0.2+13/src/java.base/unix/native/libnio/ch/UnixFileDispatcherImpl.c --- openjdk-21-21.0.1+12/src/java.base/unix/native/libnio/ch/UnixFileDispatcherImpl.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/unix/native/libnio/ch/UnixFileDispatcherImpl.c 2024-01-16 16:19:00.000000000 +0000 @@ -45,6 +45,11 @@ #define fstatvfs64 fstatvfs #endif +#if defined(__linux__) +#include +#include +#endif + #include "jni.h" #include "nio.h" #include "nio_util.h" @@ -169,7 +174,7 @@ if (fstat64(fd, &fbuf) < 0) return handle(env, -1, "Size failed"); -#ifdef BLKGETSIZE64 +#if defined(__linux__) if (S_ISBLK(fbuf.st_mode)) { uint64_t size; if (ioctl(fd, BLKGETSIZE64, &size) < 0) diff -Nru openjdk-21-21.0.1+12/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c openjdk-21-21.0.2+13/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c --- openjdk-21-21.0.1+12/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c 2024-01-16 16:19:00.000000000 +0000 @@ -51,6 +51,7 @@ #ifdef __linux__ #include +#include // makedev macros #endif #if defined(__linux__) || defined(_AIX) @@ -71,6 +72,98 @@ #define readdir64 readdir #endif +#if defined(__linux__) +// Account for the case where we compile on a system without statx +// support. We still want to ensure we can call statx at runtime +// if the runtime glibc version supports it (>= 2.28). We do this +// by defining binary compatible statx structs in this file and +// not relying on included headers. + +#ifndef __GLIBC__ +// Alpine doesn't know these types, define them +typedef unsigned int __uint32_t; +typedef unsigned short __uint16_t; +typedef unsigned long int __uint64_t; +#endif + +/* + * Timestamp structure for the timestamps in struct statx. + */ +struct my_statx_timestamp { + int64_t tv_sec; + __uint32_t tv_nsec; + int32_t __reserved; +}; + +/* + * struct statx used by statx system call on >= glibc 2.28 + * systems + */ +struct my_statx +{ + __uint32_t stx_mask; + __uint32_t stx_blksize; + __uint64_t stx_attributes; + __uint32_t stx_nlink; + __uint32_t stx_uid; + __uint32_t stx_gid; + __uint16_t stx_mode; + __uint16_t __statx_pad1[1]; + __uint64_t stx_ino; + __uint64_t stx_size; + __uint64_t stx_blocks; + __uint64_t stx_attributes_mask; + struct my_statx_timestamp stx_atime; + struct my_statx_timestamp stx_btime; + struct my_statx_timestamp stx_ctime; + struct my_statx_timestamp stx_mtime; + __uint32_t stx_rdev_major; + __uint32_t stx_rdev_minor; + __uint32_t stx_dev_major; + __uint32_t stx_dev_minor; + __uint64_t __statx_pad2[14]; +}; + +// statx masks, flags, constants + +#ifndef AT_SYMLINK_NOFOLLOW +#define AT_SYMLINK_NOFOLLOW 0x100 +#endif + +#ifndef AT_STATX_SYNC_AS_STAT +#define AT_STATX_SYNC_AS_STAT 0x0000 +#endif + +#ifndef AT_EMPTY_PATH +#define AT_EMPTY_PATH 0x1000 +#endif + +#ifndef STATX_BASIC_STATS +#define STATX_BASIC_STATS 0x000007ffU +#endif + +#ifndef STATX_BTIME +#define STATX_BTIME 0x00000800U +#endif + +#ifndef STATX_ALL +#define STATX_ALL (STATX_BTIME | STATX_BASIC_STATS) +#endif + +#ifndef AT_FDCWD +#define AT_FDCWD -100 +#endif + +#ifndef RTLD_DEFAULT +#define RTLD_DEFAULT RTLD_LOCAL +#endif + +#define NO_FOLLOW_SYMLINK 1 +#define FOLLOW_SYMLINK 0 + +#endif // __linux__ + + #include "jni.h" #include "jni_util.h" #include "jlong.h" @@ -117,9 +210,12 @@ static jfieldID attrs_st_ctime_sec; static jfieldID attrs_st_ctime_nsec; -#ifdef _DARWIN_FEATURE_64_BIT_INODE +#if defined(_DARWIN_FEATURE_64_BIT_INODE) || defined(__linux__) static jfieldID attrs_st_birthtime_sec; #endif +#if defined(__linux__) // Linux has nsec granularity if supported +static jfieldID attrs_st_birthtime_nsec; +#endif static jfieldID attrs_f_frsize; static jfieldID attrs_f_blocks; @@ -143,6 +239,10 @@ typedef int futimens_func(int, const struct timespec *); typedef int lutimes_func(const char *, const struct timeval *); typedef DIR* fdopendir_func(int); +#if defined(__linux__) +typedef int statx_func(int dirfd, const char *restrict pathname, int flags, + unsigned int mask, struct my_statx *restrict statxbuf); +#endif static openat64_func* my_openat64_func = NULL; static fstatat64_func* my_fstatat64_func = NULL; @@ -152,6 +252,9 @@ static futimens_func* my_futimens_func = NULL; static lutimes_func* my_lutimes_func = NULL; static fdopendir_func* my_fdopendir_func = NULL; +#if defined(__linux__) +static statx_func* my_statx_func = NULL; +#endif /** * fstatat missing from glibc on Linux. @@ -177,6 +280,13 @@ } #endif +#if defined(__linux__) +static int statx_wrapper(int dirfd, const char *restrict pathname, int flags, + unsigned int mask, struct my_statx *restrict statxbuf) { + return (*my_statx_func)(dirfd, pathname, flags, mask, statxbuf); +} +#endif + /** * Call this to throw an internal UnixException when a system/library * call fails @@ -229,10 +339,14 @@ attrs_st_ctime_nsec = (*env)->GetFieldID(env, clazz, "st_ctime_nsec", "J"); CHECK_NULL_RETURN(attrs_st_ctime_nsec, 0); -#ifdef _DARWIN_FEATURE_64_BIT_INODE +#if defined(_DARWIN_FEATURE_64_BIT_INODE) || defined(__linux__) attrs_st_birthtime_sec = (*env)->GetFieldID(env, clazz, "st_birthtime_sec", "J"); CHECK_NULL_RETURN(attrs_st_birthtime_sec, 0); #endif +#if defined (__linux__) // Linux has nsec granularity + attrs_st_birthtime_nsec = (*env)->GetFieldID(env, clazz, "st_birthtime_nsec", "J"); + CHECK_NULL_RETURN(attrs_st_birthtime_nsec, 0); +#endif clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes"); CHECK_NULL_RETURN(clazz, 0); @@ -314,6 +428,12 @@ #ifdef _DARWIN_FEATURE_64_BIT_INODE capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_BIRTHTIME; #endif +#if defined(__linux__) + my_statx_func = (statx_func*) dlsym(RTLD_DEFAULT, "statx"); + if (my_statx_func != NULL) { + capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_BIRTHTIME; + } +#endif /* supports extended attributes */ @@ -490,10 +610,37 @@ return (jint)n; } +#if defined(__linux__) +/** + * Copy statx members into sun.nio.fs.UnixFileAttributes + */ +static void copy_statx_attributes(JNIEnv* env, struct my_statx* buf, jobject attrs) { + (*env)->SetIntField(env, attrs, attrs_st_mode, (jint)buf->stx_mode); + (*env)->SetLongField(env, attrs, attrs_st_ino, (jlong)buf->stx_ino); + (*env)->SetIntField(env, attrs, attrs_st_nlink, (jint)buf->stx_nlink); + (*env)->SetIntField(env, attrs, attrs_st_uid, (jint)buf->stx_uid); + (*env)->SetIntField(env, attrs, attrs_st_gid, (jint)buf->stx_gid); + (*env)->SetLongField(env, attrs, attrs_st_size, (jlong)buf->stx_size); + (*env)->SetLongField(env, attrs, attrs_st_atime_sec, (jlong)buf->stx_atime.tv_sec); + (*env)->SetLongField(env, attrs, attrs_st_mtime_sec, (jlong)buf->stx_mtime.tv_sec); + (*env)->SetLongField(env, attrs, attrs_st_ctime_sec, (jlong)buf->stx_ctime.tv_sec); + (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->stx_btime.tv_sec); + (*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, (jlong)buf->stx_btime.tv_nsec); + (*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->stx_atime.tv_nsec); + (*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->stx_mtime.tv_nsec); + (*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->stx_ctime.tv_nsec); + // convert statx major:minor to dev_t using makedev + dev_t dev = makedev(buf->stx_dev_major, buf->stx_dev_minor); + dev_t rdev = makedev(buf->stx_rdev_major, buf->stx_rdev_minor); + (*env)->SetLongField(env, attrs, attrs_st_dev, (jlong)dev); + (*env)->SetLongField(env, attrs, attrs_st_rdev, (jlong)rdev); +} +#endif + /** * Copy stat64 members into sun.nio.fs.UnixFileAttributes */ -static void prepAttributes(JNIEnv* env, struct stat64* buf, jobject attrs) { +static void copy_stat64_attributes(JNIEnv* env, struct stat64* buf, jobject attrs) { (*env)->SetIntField(env, attrs, attrs_st_mode, (jint)buf->st_mode); (*env)->SetLongField(env, attrs, attrs_st_ino, (jlong)buf->st_ino); (*env)->SetLongField(env, attrs, attrs_st_dev, (jlong)buf->st_dev); @@ -508,6 +655,7 @@ #ifdef _DARWIN_FEATURE_64_BIT_INODE (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->st_birthtime); + // rely on default value of 0 for st_birthtime_nsec field on Darwin #endif #ifndef MACOSX @@ -528,10 +676,25 @@ int err; struct stat64 buf; const char* path = (const char*)jlong_to_ptr(pathAddress); - +#if defined(__linux__) + struct my_statx statx_buf; + int flags = AT_STATX_SYNC_AS_STAT; + unsigned int mask = STATX_ALL; + + if (my_statx_func != NULL) { + // Prefer statx over stat64 on Linux if it's available + RESTARTABLE(statx_wrapper(AT_FDCWD, path, flags, mask, &statx_buf), err); + if (err == 0) { + copy_statx_attributes(env, &statx_buf, attrs); + return 0; + } else { + return errno; + } + } +#endif RESTARTABLE(stat64(path, &buf), err); if (err == 0) { - prepAttributes(env, &buf, attrs); + copy_stat64_attributes(env, &buf, attrs); return 0; } else { return errno; @@ -545,12 +708,28 @@ int err; struct stat64 buf; const char* path = (const char*)jlong_to_ptr(pathAddress); - +#if defined(__linux__) + struct my_statx statx_buf; + int flags = AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW; + unsigned int mask = STATX_ALL; + + if (my_statx_func != NULL) { + // Prefer statx over stat64 on Linux if it's available + RESTARTABLE(statx_wrapper(AT_FDCWD, path, flags, mask, &statx_buf), err); + if (err == 0) { + copy_statx_attributes(env, &statx_buf, attrs); + } else { + throwUnixException(env, errno); + } + // statx was available, so return now + return; + } +#endif RESTARTABLE(lstat64(path, &buf), err); if (err == -1) { throwUnixException(env, errno); } else { - prepAttributes(env, &buf, attrs); + copy_stat64_attributes(env, &buf, attrs); } } @@ -560,12 +739,29 @@ { int err; struct stat64 buf; - +#if defined(__linux__) + struct my_statx statx_buf; + int flags = AT_EMPTY_PATH | AT_STATX_SYNC_AS_STAT; + unsigned int mask = STATX_ALL; + + if (my_statx_func != NULL) { + // statx supports FD use via dirfd iff pathname is an empty string and the + // AT_EMPTY_PATH flag is specified in flags + RESTARTABLE(statx_wrapper((int)fd, "", flags, mask, &statx_buf), err); + if (err == 0) { + copy_statx_attributes(env, &statx_buf, attrs); + } else { + throwUnixException(env, errno); + } + // statx was available, so return now + return; + } +#endif RESTARTABLE(fstat64((int)fd, &buf), err); if (err == -1) { throwUnixException(env, errno); } else { - prepAttributes(env, &buf, attrs); + copy_stat64_attributes(env, &buf, attrs); } } @@ -576,6 +772,26 @@ int err; struct stat64 buf; const char* path = (const char*)jlong_to_ptr(pathAddress); +#if defined(__linux__) + struct my_statx statx_buf; + int flags = AT_STATX_SYNC_AS_STAT; + unsigned int mask = STATX_ALL; + + if (my_statx_func != NULL) { + // Prefer statx over stat64 on Linux if it's available + if (((int)flag & AT_SYMLINK_NOFOLLOW) > 0) { // flag set in java code + flags |= AT_SYMLINK_NOFOLLOW; + } + RESTARTABLE(statx_wrapper((int)dfd, path, flags, mask, &statx_buf), err); + if (err == 0) { + copy_statx_attributes(env, &statx_buf, attrs); + } else { + throwUnixException(env, errno); + } + // statx was available, so return now + return; + } +#endif if (my_fstatat64_func == NULL) { JNU_ThrowInternalError(env, "should not reach here"); @@ -585,7 +801,7 @@ if (err == -1) { throwUnixException(env, errno); } else { - prepAttributes(env, &buf, attrs); + copy_stat64_attributes(env, &buf, attrs); } } diff -Nru openjdk-21-21.0.1+12/src/java.base/windows/native/libjli/cmdtoargs.c openjdk-21-21.0.2+13/src/java.base/windows/native/libjli/cmdtoargs.c --- openjdk-21-21.0.1+12/src/java.base/windows/native/libjli/cmdtoargs.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/windows/native/libjli/cmdtoargs.c 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, 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 @@ -324,6 +324,10 @@ bool check() { // "pgmname" rest of cmdline ie. pgmname + 2 double quotes + space + cmdline from windows char* cptr = (char*) malloc(strlen(argv[0]) + sizeof(char) * 3 + strlen(cmdline) + 1); + if (cptr == NULL) { + printf("*** cannot allocate memory\n"); + doabort(); + } _snprintf(cptr, MAX_PATH, "\"%s\" %s", argv[0], cmdline); JLI_CmdToArgs(cptr); free(cptr); diff -Nru openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c --- openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, 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 @@ -89,7 +89,7 @@ rv = connect((SOCKET)fd, &sa.sa, sa_len); if (rv == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "connect"); } else { /* Disable WSAECONNRESET errors as socket is no longer connected */ BOOL enable = FALSE; @@ -136,7 +136,10 @@ } } else if (theErr == WSAEWOULDBLOCK) { return IOS_UNAVAILABLE; - } else return handleSocketError(env, theErr); + } else { + NET_ThrowNew(env, theErr, "recvfrom"); + return IOS_THROWN; + } } } while (retry); @@ -160,7 +163,8 @@ if (theErr == WSAEWOULDBLOCK) { return IOS_UNAVAILABLE; } - return handleSocketError(env, (jint)WSAGetLastError()); + NET_ThrowNew(env, (jint)WSAGetLastError(), "sendto"); + return IOS_THROWN; } return rv; } diff -Nru openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/IOUtil.c openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/IOUtil.c --- openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/IOUtil.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/IOUtil.c 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, 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 @@ -149,8 +149,7 @@ } result = ioctlsocket(fd, FIONBIO, &argp); if (result == SOCKET_ERROR) { - int error = WSAGetLastError(); - handleSocketError(env, (jint)error); + NET_ThrowNew(env, WSAGetLastError(), "ioctlsocket"); } } diff -Nru openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/Net.c openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/Net.c --- openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/Net.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/Net.c 2024-01-16 16:19:00.000000000 +0000 @@ -77,12 +77,6 @@ NULL, 0, &bytesReturned, NULL, NULL); } -jint handleSocketError(JNIEnv *env, int errorValue) -{ - NET_ThrowNew(env, errorValue, NULL); - return IOS_THROWN; -} - static jclass isa_class; /* java.net.InetSocketAddress */ static jmethodID isa_ctorID; /* InetSocketAddress(InetAddress, int) */ @@ -392,7 +386,7 @@ n = getsockopt(fdval(env, fdo), level, opt, arg, &arglen); } if (n == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "getsockopt"); return IOS_THROWN; } @@ -436,7 +430,7 @@ n = setsockopt(fdval(env, fdo), level, opt, parg, arglen); } if (n == SOCKET_ERROR) - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "setsocketopt"); } JNIEXPORT jint JNICALL @@ -467,7 +461,7 @@ if (n == SOCKET_ERROR) { if (join && (WSAGetLastError() == WSAENOPROTOOPT)) return IOS_UNAVAILABLE; - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "setsocketopt"); } return 0; } @@ -489,7 +483,7 @@ if (n == SOCKET_ERROR) { if (block && (WSAGetLastError() == WSAENOPROTOOPT)) return IOS_UNAVAILABLE; - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "setsockopt"); } return 0; } @@ -542,7 +536,7 @@ } if (n == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "setsockopt"); } return 0; } @@ -554,7 +548,7 @@ int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE; int n = setGroupSourceReqOption(env, fdo, opt, group, index, source); if (n == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "setsocketopt to block or unblock source"); } return 0; } @@ -571,7 +565,7 @@ n = setsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF, (void*)&(in.s_addr), arglen); if (n == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "setsockopt"); } } @@ -584,7 +578,7 @@ n = getsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF, (void*)&in, &arglen); if (n == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "getsockopt"); return IOS_THROWN; } return ntohl(in.s_addr); @@ -600,7 +594,7 @@ n = setsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF, (void*)&(index), arglen); if (n == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "setsockopt"); } } @@ -613,7 +607,7 @@ n = getsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF, (void*)&index, &arglen); if (n == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "getsockopt"); return -1; } return (jint)index; @@ -631,12 +625,12 @@ JNIEXPORT jint JNICALL Java_sun_nio_ch_Net_available(JNIEnv *env, jclass cl, jobject fdo) { - int count = 0; - if (NET_SocketAvailable(fdval(env, fdo), &count) != 0) { - handleSocketError(env, WSAGetLastError()); + u_long arg; + if (ioctlsocket((SOCKET) fdval(env, fdo), FIONREAD, &arg) == SOCKET_ERROR) { + NET_ThrowNew(env, WSAGetLastError(), "ioctlsocket"); return IOS_THROWN; } - return (jint) count; + return (jint) arg; } JNIEXPORT jint JNICALL @@ -667,7 +661,7 @@ /* save last winsock error */ if (rv == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "select"); return IOS_THROWN; } else if (rv >= 0) { rv = 0; @@ -707,7 +701,7 @@ result = select(fd+1, 0, &wr, &ex, (timeout >= 0) ? &t : NULL); if (result == SOCKET_ERROR) { - handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "select"); return JNI_FALSE; } else if (result == 0) { return JNI_FALSE; @@ -727,7 +721,7 @@ NET_ThrowNew(env, lastError, "getsockopt"); } } else if (optError != NO_ERROR) { - handleSocketError(env, optError); + NET_ThrowNew(env, optError, "getsockopt"); } return JNI_FALSE; } diff -Nru openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c --- openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -118,6 +118,9 @@ if (result == SOCKET_ERROR) { if (GetLastError() == WSAENOBUFS) { infoPtr = (LPWSAPROTOCOL_INFOW)malloc(len); + if (infoPtr == NULL) { + return JNI_FALSE; + } result = WSAEnumProtocolsW(0, infoPtr, &len); if (result == SOCKET_ERROR) { free(infoPtr); @@ -158,7 +161,8 @@ { SOCKET s = WSASocketW(PF_UNIX, SOCK_STREAM, 0, &provider, 0, WSA_FLAG_OVERLAPPED); if (s == INVALID_SOCKET) { - return handleSocketError(env, WSAGetLastError()); + NET_ThrowNew(env, WSAGetLastError(), "WSASocketW"); + return IOS_THROWN; } SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0); return (int)s; diff -Nru openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/nio_util.h openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/nio_util.h --- openjdk-21-21.0.1+12/src/java.base/windows/native/libnio/ch/nio_util.h 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.base/windows/native/libnio/ch/nio_util.h 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -46,7 +46,6 @@ jint convertReturnVal(JNIEnv *env, jint n, jboolean r); jlong convertLongReturnVal(JNIEnv *env, jlong n, jboolean r); jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd); -jint handleSocketError(JNIEnv *env, int errorValue); #ifdef _WIN64 diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java openjdk-21-21.0.2+13/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java --- openjdk-21-21.0.1+12/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -560,7 +560,7 @@ "Destination ColorSpace is undefined"); } ICC_Profile destProfile = profileList[nProfiles - 1]; - cs = new ICC_ColorSpace(destProfile); + cs = createCompatibleColorSpace(destProfile); } else { /* non-ICC case */ int nSpaces = CSList.length; @@ -570,6 +570,25 @@ return createCompatibleDestImage(src, destCM, cs); } + private static ColorSpace createCompatibleColorSpace(ICC_Profile profile) { + if (profile == ICC_Profile.getInstance(ColorSpace.CS_sRGB)) { + return ColorSpace.getInstance(ColorSpace.CS_sRGB); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB)) { + return ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ)) { + return ColorSpace.getInstance(ColorSpace.CS_CIEXYZ); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_PYCC)) { + return ColorSpace.getInstance(ColorSpace.CS_PYCC); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_GRAY)) { + return ColorSpace.getInstance(ColorSpace.CS_GRAY); + } + return new ICC_ColorSpace(profile); + } + private BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM, ColorSpace destCS) { diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java --- openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java 2024-01-16 16:19:00.000000000 +0000 @@ -557,6 +557,7 @@ final int pix_boundsWidth, final int pix_boundsHeight, final int windingRule) { + this.rdrCtx.doRender = true; this.windingRule = windingRule; // bounds as half-open intervals: minX <= x < maxX and minY <= y < maxY diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java --- openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java 2024-01-16 16:19:00.000000000 +0000 @@ -78,6 +78,8 @@ final MarlinCache cache; // flag indicating the shape is stroked (1) or filled (0) int stroking = 0; + // flag indicating to render the shape + boolean doRender = false; // flag indicating to clip the shape boolean doClip = false; // flag indicating if the path is closed or not (in advance) to handle properly caps @@ -169,6 +171,7 @@ stats.totalOffHeap = 0L; } stroking = 0; + doRender = false; doClip = false; closedPath = false; clipInvScale = 0.0d; diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java --- openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java 2024-01-16 16:19:00.000000000 +0000 @@ -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. * 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,25 +170,34 @@ miterScaledLimit = miterLimit * lineWidth2; this.miterLimitSq = miterScaledLimit * miterScaledLimit; - final double limitMin = ((this.rdrCtx.clipInvScale == 0.0d) ? JOIN_ERROR - : (JOIN_ERROR * this.rdrCtx.clipInvScale)) - + lineWidth2; - - this.joinLimitMinSq = limitMin * limitMin; - + if (rdrCtx.doRender) { + final double limitMin = ((this.rdrCtx.clipInvScale == 0.0d) ? JOIN_ERROR + : (JOIN_ERROR * this.rdrCtx.clipInvScale)) + + lineWidth2; + + this.joinLimitMinSq = limitMin * limitMin; + } else { + // createStrokedShape(): disable limit checks: + this.joinLimitMinSq = 0.0; + } } else if (joinStyle == JOIN_ROUND) { - // chord: s = 2 r * sin( phi / 2) - // height: h = 2 r * sin( phi / 4)^2 - // small angles (phi < 90): - // h = s^2 / (8 r) - // so s^2 = (8 h * r) - - // height max (note ROUND_JOIN_ERROR = 8 * JOIN_ERROR) - final double limitMin = ((this.rdrCtx.clipInvScale == 0.0d) ? ROUND_JOIN_ERROR - : (ROUND_JOIN_ERROR * this.rdrCtx.clipInvScale)); - - // chord limit (s^2): - this.joinLimitMinSq = limitMin * this.lineWidth2; + if (rdrCtx.doRender) { + // chord: s = 2 r * sin( phi / 2) + // height: h = 2 r * sin( phi / 4)^2 + // small angles (phi < 90): + // h = s^2 / (8 r) + // so s^2 = (8 h * r) + + // height max (note ROUND_JOIN_ERROR = 8 * JOIN_ERROR) + final double limitMin = ((this.rdrCtx.clipInvScale == 0.0d) ? ROUND_JOIN_ERROR + : (ROUND_JOIN_ERROR * this.rdrCtx.clipInvScale)); + + // chord limit (s^2): + this.joinLimitMinSq = limitMin * this.lineWidth2; + } else { + // createStrokedShape(): disable limit checks: + this.joinLimitMinSq = 0.0; + } } this.prev = CLOSE; diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/Version.java openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/Version.java --- openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/java2d/marlin/Version.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/java2d/marlin/Version.java 2024-01-16 16:19:00.000000000 +0000 @@ -27,7 +27,7 @@ public final class Version { - private static final String VERSION = "marlin-0.9.4.6-Unsafe-OpenJDK"; + private static final String VERSION = "marlin-0.9.4.6.1-Unsafe-OpenJDK"; public static String getVersion() { return VERSION; diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/swing/CachedPainter.java openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/swing/CachedPainter.java --- openjdk-21-21.0.1+12/src/java.desktop/share/classes/sun/swing/CachedPainter.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/classes/sun/swing/CachedPainter.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2017, 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 @@ -314,8 +314,9 @@ @Override public Image getResolutionVariant(double destWidth, double destHeight) { - int w = (int) Math.ceil(destWidth); - int h = (int) Math.ceil(destHeight); + int w = (int) Math.floor(destWidth + 0.5); + int h = (int) Math.floor(destHeight + 0.5); + return getImage(PainterMultiResolutionCachedImage.class, c, baseWidth, baseHeight, w, h, args); } diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/legal/harfbuzz.md openjdk-21-21.0.2+13/src/java.desktop/share/legal/harfbuzz.md --- openjdk-21-21.0.1+12/src/java.desktop/share/legal/harfbuzz.md 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/legal/harfbuzz.md 2024-01-16 16:19:00.000000000 +0000 @@ -1,9 +1,7 @@ -## Harfbuzz v7.2.0 +## Harfbuzz v8.2.2 ### Harfbuzz License -https://github.com/harfbuzz/harfbuzz/blob/7.2.0/COPYING -
 
 HarfBuzz is licensed under the so-called "Old MIT" license.  Details follow.
@@ -14,6 +12,7 @@
 Copyright © 2018-2020  Ebrahim Byagowi
 Copyright © 2004-2013  Red Hat, Inc.
 Copyright © 2019  Facebook, Inc.
+Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
 Copyright © 2007  Chris Wilson
 Copyright © 2018-2019 Adobe Inc.
 Copyright © 2006-2023 Behdad Esfahbod
@@ -72,6 +71,15 @@
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+---------------------------------
+The below license applies to the following files:
+libharfbuzz/hb-unicode-emoji-table.hh
+
+© 2023 Unicode®, Inc.
+Unicode and the Unicode Logo are registered trademarks of Unicode, Inc.
+in the U.S. and other countries.
+For terms of use, see https://www.unicode.org/terms_of_use.html
+
 
### AUTHORS File Information diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/legal/libpng.md openjdk-21-21.0.2+13/src/java.desktop/share/legal/libpng.md --- openjdk-21-21.0.1+12/src/java.desktop/share/legal/libpng.md 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/java.desktop/share/legal/libpng.md 2024-01-16 16:19:00.000000000 +0000 @@ -1,4 +1,4 @@ -## libpng v1.6.39 +## libpng v1.6.40 ### libpng License
@@ -9,8 +9,8 @@
 PNG Reference Library License version 2
 ---------------------------------------
 
-Copyright (c) 1995-2022 The PNG Reference Library Authors.
-Copyright (c) 2018-2022 Cosmin Truta
+Copyright (c) 1995-2023 The PNG Reference Library Authors.
+Copyright (c) 2018-2023 Cosmin Truta
 Copyright (c) 1998-2018 Glenn Randers-Pehrson
 Copyright (c) 1996-1997 Andreas Dilger
 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -175,6 +175,7 @@
  * Mike Klein
  * Pascal Massimino
  * Paul Schmidt
+ * Philippe Antoine
  * Qiang Zhou
  * Sam Bushell
  * Samuel Williams
@@ -193,6 +194,7 @@
    - Matt Sarett
    - Mike Klein
    - Sami Boukortt
+   - Wan-Teh Chang
 
 The build projects, the build scripts, the test scripts, and other
 files in the "ci", "projects", "scripts" and "tests" directories, have
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh	2024-01-16 16:19:00.000000000 +0000
@@ -397,7 +397,6 @@
     TRACE_SERIALIZE (this);
 
     auto *subtable = c->serializer->start_embed ();
-    if (unlikely (!subtable)) return_trace (false);
     if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false);
 
     auto *old_subtable = get_subtable (base);
@@ -545,7 +544,8 @@
                 const IndexSubtableRecord*>> *lookup /* OUT */) const
   {
     bool start_glyph_is_set = false;
-    for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++)
+    unsigned num_glyphs = c->plan->num_output_glyphs ();
+    for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
     {
       hb_codepoint_t old_gid;
       if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue;
@@ -576,9 +576,6 @@
   {
     TRACE_SUBSET (this);
 
-    auto *dst = c->serializer->start_embed ();
-    if (unlikely (!dst)) return_trace (false);
-
     hb_vector_t> lookup;
     build_lookup (c, bitmap_size_context, &lookup);
     if (unlikely (!c->serializer->propagate_error (lookup)))
@@ -993,12 +990,10 @@
 {
   TRACE_SUBSET (this);
 
-  auto *cblc_prime = c->serializer->start_embed ();
-
   // Use a vector as a secondary buffer as the tables need to be built in parallel.
   hb_vector_t cbdt_prime;
 
-  if (unlikely (!cblc_prime)) return_trace (false);
+  auto *cblc_prime = c->serializer->start_embed ();
   if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false);
   cblc_prime->version = version;
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh	2024-01-16 16:19:00.000000000 +0000
@@ -53,6 +53,7 @@
 struct hb_paint_context_t :
        hb_dispatch_context_t
 {
+  const char *get_name () { return "PAINT"; }
   template 
   return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); }
   static return_t default_return_value () { return hb_empty_t (); }
@@ -68,6 +69,8 @@
   unsigned int palette_index;
   hb_color_t foreground;
   VarStoreInstancer &instancer;
+  hb_map_t current_glyphs;
+  hb_map_t current_layers;
   int depth_left = HB_MAX_NESTING_LEVEL;
   int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
 
@@ -261,6 +264,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     value.paint_glyph (c, varIdxBase);
   }
 
@@ -281,7 +285,7 @@
   public:
   VarIdx varIdxBase;
   public:
-  DEFINE_SIZE_STATIC (4 + T::static_size);
+  DEFINE_SIZE_MIN (VarIdx::static_size + T::min_size);
 };
 
 template 
@@ -315,6 +319,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     value.paint_glyph (c, varIdxBase);
   }
 
@@ -332,7 +337,7 @@
 
   T      value;
   public:
-  DEFINE_SIZE_STATIC (T::static_size);
+  DEFINE_SIZE_MIN (T::min_size);
 };
 
 // Color structures
@@ -409,7 +414,6 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
@@ -559,6 +563,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     c->funcs->push_transform (c->data,
                               xx.to_float (c->instancer (varIdxBase, 0)),
                               yx.to_float (c->instancer (varIdxBase, 1)),
@@ -640,6 +645,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_bool_t is_foreground;
     hb_color_t color;
 
@@ -694,6 +700,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_color_line_t cl = {
       (void *) &(this+colorLine),
       (this+colorLine).static_get_color_stops, c,
@@ -760,6 +767,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_color_line_t cl = {
       (void *) &(this+colorLine),
       (this+colorLine).static_get_color_stops, c,
@@ -824,6 +832,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_color_line_t cl = {
       (void *) &(this+colorLine),
       (this+colorLine).static_get_color_stops, c,
@@ -875,6 +884,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     c->funcs->push_inverse_root_transform (c->data, c->font);
     c->funcs->push_clip_glyph (c->data, gid, c->font);
     c->funcs->push_root_transform (c->data, c->font);
@@ -947,6 +957,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     (this+transform).paint_glyph (c);
     c->recurse (this+src);
     c->funcs->pop_transform (c->data);
@@ -991,6 +1002,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float ddx = dx + c->instancer (varIdxBase, 0);
     float ddy = dy + c->instancer (varIdxBase, 1);
 
@@ -1039,6 +1051,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
     float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
 
@@ -1089,6 +1102,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
     float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
     float tCenterX = centerX + c->instancer (varIdxBase, 2);
@@ -1142,6 +1156,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float s = scale.to_float (c->instancer (varIdxBase, 0));
 
     bool p1 = c->funcs->push_scale (c->data, s, s);
@@ -1189,6 +1204,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float s = scale.to_float (c->instancer (varIdxBase, 0));
     float tCenterX = centerX + c->instancer (varIdxBase, 1);
     float tCenterY = centerY + c->instancer (varIdxBase, 2);
@@ -1240,6 +1256,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float a = angle.to_float (c->instancer (varIdxBase, 0));
 
     bool p1 = c->funcs->push_rotate (c->data, a);
@@ -1287,6 +1304,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float a = angle.to_float (c->instancer (varIdxBase, 0));
     float tCenterX = centerX + c->instancer (varIdxBase, 1);
     float tCenterY = centerY + c->instancer (varIdxBase, 2);
@@ -1341,6 +1359,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
     float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
 
@@ -1391,6 +1410,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
     float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
     float tCenterX = centerX + c->instancer (varIdxBase, 2);
@@ -1426,20 +1446,24 @@
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false);
-    return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer));
+    bool ret = false;
+    ret |= out->src.serialize_subset (c, src, this, instancer);
+    ret |= out->backdrop.serialize_subset (c, backdrop, this, instancer);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
+                  c->check_ops (this->min_size) && // PainComposite can get exponential
                   src.sanitize (c, this) &&
                   backdrop.sanitize (c, this));
   }
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     c->recurse (this+backdrop);
     c->funcs->push_group (c->data);
     c->recurse (this+src);
@@ -1514,10 +1538,10 @@
     value.get_clip_box(clip_box, instancer);
     if (instancer)
     {
-      clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
-      clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
-      clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
-      clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
+      clip_box.xMin += roundf (instancer (varIdxBase, 0));
+      clip_box.yMin += roundf (instancer (varIdxBase, 1));
+      clip_box.xMax += roundf (instancer (varIdxBase, 2));
+      clip_box.yMax += roundf (instancer (varIdxBase, 3));
     }
   }
 };
@@ -1898,15 +1922,16 @@
     auto *out = c->serializer->start_embed (this);
     if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
 
+    bool ret = false;
     for (const auto& _ : + hb_enumerate (*this)
                          | hb_filter (c->plan->colrv1_layers, hb_first))
 
     {
       auto *o = out->serialize_append (c->serializer);
-      if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer))
-        return_trace (false);
+      if (unlikely (!o)) return_trace (false);
+      ret |= o->serialize_subset (c, _.second, this, instancer);
     }
-    return_trace (true);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2167,7 +2192,7 @@
     if (version == 0 && (!base_it || !layer_it))
       return_trace (false);
 
-    COLR *colr_prime = c->serializer->start_embed ();
+    auto *colr_prime = c->serializer->start_embed ();
     if (unlikely (!c->serializer->extend_min (colr_prime)))  return_trace (false);
 
     if (version == 0)
@@ -2284,6 +2309,7 @@
                                  &(this+varIdxMap),
                                  hb_array (font->coords, font->num_coords));
     hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
+    c.current_glyphs.add (glyph);
 
     if (version == 1)
     {
@@ -2399,18 +2425,42 @@
 
 void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
 {
+  TRACE_PAINT (this);
   const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
   for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
   {
+    if (unlikely (c->current_layers.has (i)))
+      continue;
+
+    c->current_layers.add (i);
+
     const Paint &paint = paint_offset_lists.get_paint (i);
     c->funcs->push_group (c->data);
     c->recurse (paint);
     c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+
+    c->current_layers.del (i);
   }
 }
 
 void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
 {
+  TRACE_PAINT (this);
+
+  if (unlikely (c->current_glyphs.has (gid)))
+    return;
+
+  c->current_glyphs.add (gid);
+
+  c->funcs->push_inverse_root_transform (c->data, c->font);
+  if (c->funcs->color_glyph (c->data, gid, c->font))
+  {
+    c->funcs->pop_transform (c->data);
+    c->current_glyphs.del (gid);
+    return;
+  }
+  c->funcs->pop_transform (c->data);
+
   const COLR *colr_table = c->get_colr_table ();
   const Paint *paint = colr_table->get_base_glyph_paint (gid);
 
@@ -2429,6 +2479,8 @@
 
   if (has_clip_box)
     c->funcs->pop_clip (c->data);
+
+  c->current_glyphs.del (gid);
 }
 
 } /* namespace OT */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh	2024-01-16 16:19:00.000000000 +0000
@@ -48,7 +48,6 @@
   {
     TRACE_SERIALIZE (this);
     SBIXGlyph* new_glyph = c->start_embed ();
-    if (unlikely (!new_glyph)) return_trace (nullptr);
     if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
 
     new_glyph->xOffset = xOffset;
@@ -143,7 +142,6 @@
     unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
 
     auto* out = c->serializer->start_embed ();
-    if (unlikely (!out)) return_trace (false);
     auto snap = c->serializer->snapshot ();
     if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
     out->ppem = ppem;
@@ -388,7 +386,6 @@
     TRACE_SERIALIZE (this);
 
     auto *out = c->serializer->start_embed> ();
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     hb_vector_t*> new_strikes;
@@ -423,8 +420,6 @@
   {
     TRACE_SUBSET (this);
 
-    sbix *sbix_prime = c->serializer->start_embed ();
-    if (unlikely (!sbix_prime)) return_trace (false);
     if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
     if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh	2024-01-16 16:19:00.000000000 +0000
@@ -57,6 +57,9 @@
   public:
   DEFINE_SIZE_UNION (2, format);
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -113,22 +116,33 @@
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
 
-    unsigned count = 0;
+    unsigned count = hb_len (glyphs);
     unsigned num_ranges = 0;
     hb_codepoint_t last = (hb_codepoint_t) -2;
+    hb_codepoint_t max = 0;
+    bool unsorted = false;
     for (auto g: glyphs)
     {
+      if (last != (hb_codepoint_t) -2 && g < last)
+        unsorted = true;
       if (last + 1 != g)
         num_ranges++;
       last = g;
-      count++;
+      if (g > max) max = g;
     }
-    u.format = count <= num_ranges * 3 ? 1 : 2;
+    u.format = !unsorted && count <= num_ranges * 3 ? 1 : 2;
 
 #ifndef HB_NO_BEYOND_64K
-    if (count && last > 0xFFFFu)
+    if (max > 0xFFFFu)
       u.format += 2;
+    if (unlikely (max > 0xFFFFFFu))
+#else
+    if (unlikely (max > 0xFFFFu))
 #endif
+    {
+      c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+      return_trace (false);
+    }
 
     switch (u.format)
     {
@@ -148,8 +162,8 @@
     auto it =
     + iter ()
     | hb_take (c->plan->source->get_num_glyphs ())
-    | hb_filter (c->plan->glyph_map_gsub)
     | hb_map_retains_sorting (c->plan->glyph_map_gsub)
+    | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
     ;
 
     // Cache the iterator result as it will be iterated multiple times
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -79,7 +79,7 @@
   {
     if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      for (auto g : *glyphs)
         if (get_coverage (g) != NOT_COVERED)
           return true;
       return false;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh	2024-01-16 16:19:00.000000000 +0000
@@ -95,19 +95,26 @@
     unsigned count = 0;
     unsigned range = (unsigned) -1;
     last = (hb_codepoint_t) -2;
+    unsigned unsorted = false;
     for (auto g: glyphs)
     {
       if (last + 1 != g)
       {
+        if (unlikely (last != (hb_codepoint_t) -2 && last + 1 > g))
+          unsorted = true;
+
         range++;
-        rangeRecord[range].first = g;
-        rangeRecord[range].value = count;
+        rangeRecord.arrayZ[range].first = g;
+        rangeRecord.arrayZ[range].value = count;
       }
-      rangeRecord[range].last = g;
+      rangeRecord.arrayZ[range].last = g;
       last = g;
       count++;
     }
 
+    if (unlikely (unsorted))
+      rangeRecord.as_array ().qsort (RangeRecord::cmp_range);
+
     return_trace (true);
   }
 
@@ -115,7 +122,7 @@
   {
     if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      for (auto g : *glyphs)
         if (get_coverage (g) != NOT_COVERED)
           return true;
       return false;
@@ -185,8 +192,8 @@
         if (__more__ ())
         {
           unsigned int old = coverage;
-          j = c->rangeRecord[i].first;
-          coverage = c->rangeRecord[i].value;
+          j = c->rangeRecord.arrayZ[i].first;
+          coverage = c->rangeRecord.arrayZ[i].value;
           if (unlikely (coverage != old + 1))
           {
             /* Broken table. Skip. Important to avoid DoS.
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh	2024-01-16 16:19:00.000000000 +0000
@@ -51,6 +51,18 @@
   int cmp (hb_codepoint_t g) const
   { return g < first ? -1 : g <= last ? 0 : +1; }
 
+  HB_INTERNAL static int cmp_range (const void *pa, const void *pb) {
+    const RangeRecord *a = (const RangeRecord *) pa;
+    const RangeRecord *b = (const RangeRecord *) pb;
+    if (a->first < b->first) return -1;
+    if (a->first > b->first) return +1;
+    if (a->last < b->last) return -1;
+    if (a->last > b->last) return +1;
+    if (a->value < b->value) return -1;
+    if (a->value > b->value) return +1;
+    return 0;
+  }
+
   unsigned get_population () const
   {
     if (unlikely (last < first)) return 0;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh	2024-01-16 16:19:00.000000000 +0000
@@ -29,9 +29,10 @@
 #ifndef OT_LAYOUT_GDEF_GDEF_HH
 #define OT_LAYOUT_GDEF_GDEF_HH
 
-#include "../../../hb-ot-layout-common.hh"
+#include "../../../hb-ot-var-common.hh"
 
 #include "../../../hb-font.hh"
+#include "../../../hb-cache.hh"
 
 
 namespace OT {
@@ -48,8 +49,6 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
-
     return_trace (out->serialize (c->serializer, + iter ()));
   }
 };
@@ -201,22 +200,23 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
     if (!c->serializer->embed (caretValueFormat)) return_trace (false);
     if (!c->serializer->embed (coordinate)) return_trace (false);
 
     unsigned varidx = (this+deviceTable).get_variation_index ();
-    if (c->plan->layout_variation_idx_delta_map.has (varidx))
+    hb_pair_t *new_varidx_delta;
+    if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta))
+      return_trace (false);
+
+    uint32_t new_varidx = hb_first (*new_varidx_delta);
+    int delta = hb_second (*new_varidx_delta);
+    if (delta != 0)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx));
-      if (delta != 0)
-      {
-        if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
-          return_trace (false);
-      }
+      if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+        return_trace (false);
     }
 
-    if (c->plan->all_axes_pinned)
+    if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
       return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
 
     if (!c->serializer->embed (deviceTable))
@@ -441,6 +441,16 @@
   bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
   { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
 
+  template 
+  void collect_coverage (hb_vector_t &sets) const
+  {
+     for (const auto &offset : coverage)
+     {
+       const auto &cov = this+offset;
+       cov.collect_coverage (sets.push ());
+     }
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -494,6 +504,15 @@
     }
   }
 
+  template 
+  void collect_coverage (hb_vector_t &sets) const
+  {
+    switch (u.format) {
+    case 1: u.format1.collect_coverage (sets); return;
+    default:return;
+    }
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -585,6 +604,26 @@
                   (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
   }
 
+  static void remap_varidx_after_instantiation (const hb_map_t& varidx_map,
+                                                hb_hashmap_t>& layout_variation_idx_delta_map /* IN/OUT */)
+  {
+    /* varidx_map is empty which means varstore is empty after instantiation,
+     * no variations, map all varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX.
+     * varidx_map doesn't have original varidx, indicating delta row is all
+     * zeros, map varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    for (auto _ : layout_variation_idx_delta_map.iter_ref ())
+    {
+      /* old_varidx->(varidx, delta) mapping generated for subsetting, then this
+       * varidx is used as key of varidx_map during instantiation */
+      uint32_t varidx = _.second.first;
+      uint32_t *new_varidx;
+      if (varidx_map.has (varidx, &new_varidx))
+        _.second.first = *new_varidx;
+      else
+        _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
+    }
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -607,6 +646,22 @@
     {
       if (c->plan->all_axes_pinned)
         out->varStore = 0;
+      else if (c->plan->normalized_coords)
+      {
+        if (varStore)
+        {
+          item_variations_t item_vars;
+          if (item_vars.instantiate (this+varStore, c->plan, true, true,
+                                     c->plan->gdef_varstore_inner_maps.as_array ()))
+            subset_varstore = out->varStore.serialize_serialize (c->serializer,
+                                                                 item_vars.has_long_word (),
+                                                                 c->plan->axis_tags,
+                                                                 item_vars.get_region_list (),
+                                                                 item_vars.get_vardata_encodings ());
+          remap_varidx_after_instantiation (item_vars.get_varidx_map (),
+                                            c->plan->layout_variation_idx_delta_map);
+        }
+      }
       else
         subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
     }
@@ -858,27 +913,79 @@
         hb_blob_destroy (table.get_blob ());
         table = hb_blob_get_empty ();
       }
+
+#ifndef HB_NO_GDEF_CACHE
+      table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests);
+#endif
     }
     ~accelerator_t () { table.destroy (); }
 
+    unsigned int get_glyph_props (hb_codepoint_t glyph) const
+    {
+      unsigned v;
+
+#ifndef HB_NO_GDEF_CACHE
+      if (glyph_props_cache.get (glyph, &v))
+        return v;
+#endif
+
+      v = table->get_glyph_props (glyph);
+
+#ifndef HB_NO_GDEF_CACHE
+      if (likely (table.get_blob ())) // Don't try setting if we are the null instance!
+        glyph_props_cache.set (glyph, v);
+#endif
+
+      return v;
+
+    }
+
+    bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+    {
+      return
+#ifndef HB_NO_GDEF_CACHE
+             mark_glyph_set_digests[set_index].may_have (glyph_id) &&
+#endif
+             table->mark_set_covers (set_index, glyph_id);
+    }
+
     hb_blob_ptr_t table;
+#ifndef HB_NO_GDEF_CACHE
+    hb_vector_t mark_glyph_set_digests;
+    mutable hb_cache_t<21, 3, 8> glyph_props_cache;
+#endif
   };
 
   void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
   { get_lig_caret_list ().collect_variation_indices (c); }
 
   void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
+                                       const hb_vector_t& normalized_coords,
+                                       bool calculate_delta, /* not pinned at default */
+                                       bool no_variations, /* all axes pinned */
                                        hb_hashmap_t> *layout_variation_idx_delta_map /* OUT */) const
   {
     if (!has_var_store ()) return;
-    if (layout_variation_indices->is_empty ()) return;
+    const VariationStore &var_store = get_var_store ();
+    float *store_cache = var_store.create_cache ();
 
     unsigned new_major = 0, new_minor = 0;
     unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
     for (unsigned idx : layout_variation_indices->iter ())
     {
+      int delta = 0;
+      if (calculate_delta)
+        delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ,
+                                             normalized_coords.length, store_cache));
+
+      if (no_variations)
+      {
+        layout_variation_idx_delta_map->set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
+        continue;
+      }
+
       uint16_t major = idx >> 16;
-      if (major >= get_var_store ().get_sub_table_count ()) break;
+      if (major >= var_store.get_sub_table_count ()) break;
       if (major != last_major)
       {
         new_minor = 0;
@@ -886,14 +993,11 @@
       }
 
       unsigned new_idx = (new_major << 16) + new_minor;
-      if (!layout_variation_idx_delta_map->has (idx))
-        continue;
-      int delta = hb_second (layout_variation_idx_delta_map->get (idx));
-
       layout_variation_idx_delta_map->set (idx, hb_pair_t (new_idx, delta));
       ++new_minor;
       last_major = major;
     }
+    var_store.destroy_cache (store_cache);
   }
 
   protected:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh	2024-01-16 16:19:00.000000000 +0000
@@ -25,7 +25,9 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
+    if (unlikely (!c->check_struct (this))) return_trace (false);
+
+    return_trace (xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
   }
 
   void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
@@ -35,9 +37,9 @@
     *x = font->em_fscale_x (xCoordinate);
     *y = font->em_fscale_y (yCoordinate);
 
-    if (font->x_ppem || font->num_coords)
+    if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this))
       *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
-    if (font->y_ppem || font->num_coords)
+    if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this))
       *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
   }
 
@@ -45,15 +47,19 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->embed (format))) return_trace (false);
     if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false);
     if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
 
     unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map.has (x_varidx))
+    if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx));
+      hb_pair_t *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta))
+        return_trace (false);
+
+      x_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
@@ -63,9 +69,14 @@
     }
 
     unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map.has (y_varidx))
+    if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx));
+      hb_pair_t *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta))
+        return_trace (false);
+
+      y_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
@@ -74,7 +85,10 @@
       }
     }
 
-    if (c->plan->all_axes_pinned)
+    /* in case that all axes are pinned or no variations after instantiation,
+     * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX &&
+        y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
       return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
 
     if (!c->serializer->embed (xDeviceTable)) return_trace (false);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh	2024-01-16 16:19:00.000000000 +0000
@@ -21,18 +21,25 @@
     if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
     unsigned int count = rows * cols;
     if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (true);
+
     for (unsigned int i = 0; i < count; i++)
       if (!matrixZ[i].sanitize (c, this)) return_trace (false);
     return_trace (true);
   }
 
-  const Anchor& get_anchor (unsigned int row, unsigned int col,
+  const Anchor& get_anchor (hb_ot_apply_context_t *c,
+                            unsigned int row, unsigned int col,
                             unsigned int cols, bool *found) const
   {
     *found = false;
     if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
-    *found = !matrixZ[row * cols + col].is_null ();
-    return this+matrixZ[row * cols + col];
+    auto &offset = matrixZ[row * cols + col];
+    if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor);
+    *found = !offset.is_null ();
+    return this+offset;
   }
 
   template serializer->extend_min (out)))  return_trace (false);
 
     out->rows = num_rows;
+    bool ret = false;
     for (const unsigned i : index_iter)
     {
       auto *offset = c->serializer->embed (matrixZ[i]);
       if (!offset) return_trace (false);
-      offset->serialize_subset (c, matrixZ[i], this);
+      ret |= offset->serialize_subset (c, matrixZ[i], this);
     }
 
-    return_trace (true);
+    return_trace (ret);
   }
 };
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -24,16 +24,17 @@
     (src_base+exitAnchor).collect_variation_indices (c);
   }
 
-  EntryExitRecord* subset (hb_subset_context_t *c,
-                           const void *src_base) const
+  bool subset (hb_subset_context_t *c,
+               const void *src_base) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
+    if (unlikely (!out)) return_trace (false);
 
-    out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
-    out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
-    return_trace (out);
+    bool ret = false;
+    ret |= out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
+    ret |= out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
+    return_trace (ret);
   }
 
   protected:
@@ -91,7 +92,13 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
+    if (unlikely (!coverage.sanitize (c, this)))
+      return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (entryExitRecord.sanitize_shallow (c));
+    else
+      return_trace (entryExitRecord.sanitize (c, this));
   }
 
   bool intersects (const hb_set_t *glyphs) const
@@ -119,19 +126,21 @@
     hb_buffer_t *buffer = c->buffer;
 
     const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage  (buffer->cur().codepoint)];
-    if (!this_record.entryAnchor) return_trace (false);
+    if (!this_record.entryAnchor ||
+        unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false);
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     unsigned unsafe_from;
-    if (!skippy_iter.prev (&unsafe_from))
+    if (unlikely (!skippy_iter.prev (&unsafe_from)))
     {
       buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
       return_trace (false);
     }
 
     const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
-    if (!prev_record.exitAnchor)
+    if (!prev_record.exitAnchor ||
+        unlikely (!prev_record.exitAnchor.sanitize (&c->sanitizer, this)))
     {
       buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
       return_trace (false);
@@ -200,8 +209,8 @@
      * Arabic. */
     unsigned int child  = i;
     unsigned int parent = j;
-    hb_position_t x_offset = entry_x - exit_x;
-    hb_position_t y_offset = entry_y - exit_y;
+    hb_position_t x_offset = roundf (entry_x - exit_x);
+    hb_position_t y_offset = roundf (entry_y - exit_y);
     if  (!(c->lookup_props & LookupFlag::RightToLeft))
     {
       unsigned int k = child;
@@ -278,7 +287,6 @@
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
 
     auto it =
     + hb_zip (this+coverage, entryExitRecord)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh	2024-01-16 16:19:00.000000000 +0000
@@ -156,7 +156,7 @@
   {
     for (unsigned i = 0; i < len; i++)
       if (unlikely (pos[i].y_offset))
-        pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
+        pos[i].x_offset += roundf (font->slant_xy * pos[i].y_offset);
   }
 }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh	2024-01-16 16:19:00.000000000 +0000
@@ -27,6 +27,7 @@
     auto *out = c->serializer->start_embed (this);
     if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
 
+    bool ret = false;
     for (const auto _ : + hb_zip (coverage, *this)
                   | hb_filter (glyphset, hb_first))
     {
@@ -38,13 +39,13 @@
           + hb_range (src.rows * class_count)
           | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
           ;
-      matrix->serialize_subset (c,
-                                _.second,
-                                this,
-                                src.rows,
-                                indexes);
+      ret |= matrix->serialize_subset (c,
+                                       _.second,
+                                       this,
+                                       src.rows,
+                                       indexes);
     }
-    return_trace (this->len);
+    return_trace (ret);
   }
 };
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh	2024-01-16 16:19:00.000000000 +0000
@@ -28,7 +28,7 @@
 
     const Anchor& mark_anchor = this + record.markAnchor;
     bool found;
-    const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
+    const Anchor& glyph_anchor = anchors.get_anchor (c, glyph_index, mark_class, class_count, &found);
     /* If this subtable doesn't have an anchor for this base and this class,
      * return false such that the subsequent subtables have a chance at it. */
     if (unlikely (!found)) return_trace (false);
@@ -82,10 +82,10 @@
     | hb_map (hb_second)
     ;
 
+    bool ret = false;
     unsigned new_length = 0;
     for (const auto& mark_record : mark_iter) {
-      if (unlikely (!mark_record.subset (c, this, klass_mapping)))
-        return_trace (false);
+      ret |= mark_record.subset (c, this, klass_mapping);
       new_length++;
     }
 
@@ -93,7 +93,7 @@
                                                 HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)))
       return_trace (false);
 
-    return_trace (true);
+    return_trace (ret);
   }
 };
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -197,9 +197,10 @@
     if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
       return_trace (false);
 
-    out->markArray.serialize_subset (c, markArray, this,
-                                     (this+markCoverage).iter (),
-                                     &klass_mapping);
+    if (unlikely (!out->markArray.serialize_subset (c, markArray, this,
+                                                    (this+markCoverage).iter (),
+                                                    &klass_mapping)))
+      return_trace (false);
 
     unsigned basecount = (this+baseArray).rows;
     auto base_iter =
@@ -228,11 +229,9 @@
       ;
     }
 
-    out->baseArray.serialize_subset (c, baseArray, this,
-                                     base_iter.len (),
-                                     base_indexes.iter ());
-
-    return_trace (true);
+    return_trace (out->baseArray.serialize_subset (c, baseArray, this,
+                                                   base_iter.len (),
+                                                   base_indexes.iter ()));
   }
 };
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -169,7 +169,7 @@
   {
     TRACE_SUBSET (this);
     const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
+    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
 
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
@@ -195,23 +195,24 @@
     if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage))
       return_trace (false);
 
-    out->markArray.serialize_subset (c, markArray, this,
-                                     (this+markCoverage).iter (),
-                                     &klass_mapping);
+    if (unlikely (!out->markArray.serialize_subset (c, markArray, this,
+                                                    (this+markCoverage).iter (),
+                                                    &klass_mapping)))
+      return_trace (false);
 
     auto new_ligature_coverage =
     + hb_iter (this + ligatureCoverage)
-    | hb_filter (glyphset)
+    | hb_take ((this + ligatureArray).len)
     | hb_map_retains_sorting (glyph_map)
+    | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
     ;
 
     if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
       return_trace (false);
 
-    out->ligatureArray.serialize_subset (c, ligatureArray, this,
-                                         hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
-
-    return_trace (true);
+    return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this,
+                                                       hb_iter (this+ligatureCoverage),
+                                                       classCount, &klass_mapping));
   }
 
 };
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -100,16 +100,16 @@
 
     /* now we search backwards for a suitable mark glyph until a non-mark glyph */
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
     unsigned unsafe_from;
-    if (!skippy_iter.prev (&unsafe_from))
+    if (unlikely (!skippy_iter.prev (&unsafe_from)))
     {
       buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
       return_trace (false);
     }
 
-    if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
+    if (likely (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])))
     {
       buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
       return_trace (false);
@@ -183,9 +183,10 @@
     if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
       return_trace (false);
 
-    out->mark1Array.serialize_subset (c, mark1Array, this,
-                                      (this+mark1Coverage).iter (),
-                                      &klass_mapping);
+    if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this,
+                                                     (this+mark1Coverage).iter (),
+                                                     &klass_mapping)))
+      return_trace (false);
 
     unsigned mark2count = (this+mark2Array).rows;
     auto mark2_iter =
@@ -214,9 +215,10 @@
       ;
     }
 
-    out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ());
+    return_trace (out->mark2Array.serialize_subset (c, mark2Array, this,
+                                                    mark2_iter.len (),
+                                                    mark2_indexes.iter ()));
 
-    return_trace (true);
   }
 };
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh	2024-01-16 16:19:00.000000000 +0000
@@ -24,17 +24,16 @@
     return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
   }
 
-  MarkRecord *subset (hb_subset_context_t    *c,
-                      const void             *src_base,
-                      const hb_map_t         *klass_mapping) const
+  bool subset (hb_subset_context_t    *c,
+               const void             *src_base,
+               const hb_map_t         *klass_mapping) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
+    if (unlikely (!out)) return_trace (false);
 
     out->klass = klass_mapping->get (klass);
-    out->markAnchor.serialize_subset (c, markAnchor, src_base);
-    return_trace (out);
+    return_trace (out->markAnchor.serialize_subset (c, markAnchor, src_base));
   }
 
   void collect_variation_indices (hb_collect_variation_indices_context_t *c,
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -110,9 +110,9 @@
     if (likely (index == NOT_COVERED)) return_trace (false);
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     unsigned unsafe_to;
-    if (!skippy_iter.next (&unsafe_to))
+    if (unlikely (!skippy_iter.next (&unsafe_to)))
     {
       buffer->unsafe_to_concat (buffer->idx, unsafe_to);
       return_trace (false);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh	2024-01-16 16:19:00.000000000 +0000
@@ -50,13 +50,13 @@
     unsigned int len1 = valueFormat1.get_len ();
     unsigned int len2 = valueFormat2.get_len ();
     unsigned int stride = HBUINT16::static_size * (len1 + len2);
-    unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
     unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
     return_trace (c->check_range ((const void *) values,
                                   count,
-                                  record_size) &&
-                  valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
-                  valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
+                                  stride) &&
+                  (c->lazy_some_gpos ||
+                   (valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
+                    valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride))));
   }
 
   bool intersects (const hb_set_t *glyphs) const
@@ -131,40 +131,46 @@
     if (likely (index == NOT_COVERED)) return_trace (false);
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     unsigned unsafe_to;
-    if (!skippy_iter.next (&unsafe_to))
+    if (unlikely (!skippy_iter.next (&unsafe_to)))
     {
       buffer->unsafe_to_concat (buffer->idx, unsafe_to);
       return_trace (false);
     }
 
-    unsigned int len1 = valueFormat1.get_len ();
-    unsigned int len2 = valueFormat2.get_len ();
-    unsigned int record_len = len1 + len2;
+    unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
+    if (!klass2)
+    {
+      buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+      return_trace (false);
+    }
 
     unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
-    unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
     if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
     {
       buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
       return_trace (false);
     }
 
+    unsigned int len1 = valueFormat1.get_len ();
+    unsigned int len2 = valueFormat2.get_len ();
+    unsigned int record_len = len1 + len2;
+
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
 
     bool applied_first = false, applied_second = false;
 
 
     /* Isolate simple kerning and apply it half to each side.
-     * Results in better cursor positinoing / underline drawing.
+     * Results in better cursor positioning / underline drawing.
      *
      * Disabled, because causes issues... :-(
      * https://github.com/harfbuzz/harfbuzz/issues/3408
      * https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
      */
 #ifndef HB_SPLIT_KERN
-    if (0)
+    if (false)
 #endif
     {
       if (!len2)
@@ -224,8 +230,8 @@
                           c->buffer->idx, skippy_iter.idx);
     }
 
-    applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
-    applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+    applied_first = len1 && valueFormat1.apply_value (c, this, v, buffer->cur_pos());
+    applied_second = len2 && valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
 
     if (applied_first || applied_second)
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
@@ -293,11 +299,13 @@
       out->valueFormat2 = out->valueFormat2.drop_device_table_flags ();
     }
 
+    unsigned total_len = len1 + len2;
+    hb_vector_t class2_idxs (+ hb_range ((unsigned) class2Count) | hb_filter (klass2_map));
     for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
     {
-      for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
+      for (unsigned class2_idx : class2_idxs)
       {
-        unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+        unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * total_len;
         valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], &c->plan->layout_variation_idx_delta_map);
         valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], &c->plan->layout_variation_idx_delta_map);
       }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh	2024-01-16 16:19:00.000000000 +0000
@@ -52,8 +52,9 @@
 
     unsigned int count = len;
     const PairValueRecord *record = &firstPairValueRecord;
-    return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
-                  closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
+    return_trace (c->lazy_some_gpos ||
+                  (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
+                   closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)));
   }
 
   bool intersects (const hb_set_t *glyphs,
@@ -120,8 +121,8 @@
                             c->buffer->idx, pos);
       }
 
-      bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
-      bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+      bool applied_first = len1 && valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
+      bool applied_second = len2 && valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
 
       if (applied_first || applied_second)
         if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh	2024-01-16 16:19:00.000000000 +0000
@@ -22,7 +22,7 @@
   ValueRecord   values;                 /* Positioning data for the first glyph
                                          * followed by for second glyph */
   public:
-  DEFINE_SIZE_ARRAY (Types::size, values);
+  DEFINE_SIZE_ARRAY (Types::HBGlyphID::static_size, values);
 
   int cmp (hb_codepoint_t k) const
   { return secondGlyph.cmp (k); }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -90,6 +90,7 @@
 
   bool
   position_single (hb_font_t           *font,
+                   hb_blob_t           *table_blob,
                    hb_direction_t       direction,
                    hb_codepoint_t       gid,
                    hb_glyph_position_t &pos) const
@@ -100,7 +101,7 @@
     /* This is ugly... */
     hb_buffer_t buffer;
     buffer.props.direction = direction;
-    OT::hb_ot_apply_context_t c (1, font, &buffer);
+    OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob);
 
     valueFormat.apply_value (&c, this, values, pos);
     return true;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh	2024-01-16 16:19:00.000000000 +0000
@@ -94,6 +94,7 @@
 
   bool
   position_single (hb_font_t           *font,
+                   hb_blob_t           *table_blob,
                    hb_direction_t       direction,
                    hb_codepoint_t       gid,
                    hb_glyph_position_t &pos) const
@@ -105,7 +106,7 @@
     /* This is ugly... */
     hb_buffer_t buffer;
     buffer.props.direction = direction;
-    OT::hb_ot_apply_context_t c (1, font, &buffer);
+    OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob);
 
     valueFormat.apply_value (&c, this,
                              &values[index * valueFormat.get_len ()],
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh	2024-01-16 16:19:00.000000000 +0000
@@ -118,21 +118,25 @@
     auto *cache = c->var_store_cache;
 
     /* pixel -> fractional pixel */
-    if (format & xPlaDevice) {
-      if (use_x_device) glyph_pos.x_offset  += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
+    if (format & xPlaDevice)
+    {
+      if (use_x_device) glyph_pos.x_offset  += get_device (values, &ret, base, c->sanitizer).get_x_delta (font, store, cache);
       values++;
     }
-    if (format & yPlaDevice) {
-      if (use_y_device) glyph_pos.y_offset  += (base + get_device (values, &ret)).get_y_delta (font, store, cache);
+    if (format & yPlaDevice)
+    {
+      if (use_y_device) glyph_pos.y_offset  += get_device (values, &ret, base, c->sanitizer).get_y_delta (font, store, cache);
       values++;
     }
-    if (format & xAdvDevice) {
-      if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
+    if (format & xAdvDevice)
+    {
+      if (horizontal && use_x_device) glyph_pos.x_advance += get_device (values, &ret, base, c->sanitizer).get_x_delta (font, store, cache);
       values++;
     }
-    if (format & yAdvDevice) {
+    if (format & yAdvDevice)
+    {
       /* y_advance values grow downward but font-space grows upward, hence negation */
-      if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store, cache);
+      if (!horizontal && use_y_device) glyph_pos.y_advance -= get_device (values, &ret, base, c->sanitizer).get_y_delta (font, store, cache);
       values++;
     }
     return ret;
@@ -174,6 +178,9 @@
     if (format & xAdvance)   x_adv = copy_value (c, new_format, xAdvance, *values++);
     if (format & yAdvance)   y_adv = copy_value (c, new_format, yAdvance, *values++);
 
+    if (!has_device ())
+      return;
+
     if (format & xPlaDevice)
     {
       add_delta_to_value (x_placement, base, values, layout_variation_idx_delta_map);
@@ -233,14 +240,12 @@
 
     if (format & ValueFormat::xAdvDevice)
     {
-
       (base + get_device (&(values[i]))).collect_variation_indices (c);
       i++;
     }
 
     if (format & ValueFormat::yAdvDevice)
     {
-
       (base + get_device (&(values[i]))).collect_variation_indices (c);
       i++;
     }
@@ -277,11 +282,23 @@
   {
     return *static_cast *> (value);
   }
-  static inline const Offset16To& get_device (const Value* value, bool *worked=nullptr)
+  static inline const Offset16To& get_device (const Value* value)
   {
-    if (worked) *worked |= bool (*value);
     return *static_cast *> (value);
   }
+  static inline const Device& get_device (const Value* value,
+                                          bool *worked,
+                                          const void *base,
+                                          hb_sanitize_context_t &c)
+  {
+    if (worked) *worked |= bool (*value);
+    auto &offset = *static_cast *> (value);
+
+    if (unlikely (!offset.sanitize (&c, base)))
+      return Null(Device);
+
+    return base + offset;
+  }
 
   void add_delta_to_value (HBINT16 *value,
                            const void *base,
@@ -340,25 +357,26 @@
   bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
+
+    if (unlikely (!c->check_range (values, get_size ()))) return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (true);
+
+    return_trace (!has_device () || sanitize_value_devices (c, base, values));
   }
 
   bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
   {
     TRACE_SANITIZE (this);
-    unsigned int len = get_len ();
+    unsigned size = get_size ();
 
-    if (!c->check_range (values, count, get_size ())) return_trace (false);
+    if (!c->check_range (values, count, size)) return_trace (false);
 
-    if (!has_device ()) return_trace (true);
-
-    for (unsigned int i = 0; i < count; i++) {
-      if (!sanitize_value_devices (c, base, values))
-        return_trace (false);
-      values += len;
-    }
+    if (c->lazy_some_gpos)
+      return_trace (true);
 
-    return_trace (true);
+    return_trace (sanitize_values_stride_unsafe (c, base, values, count, size));
   }
 
   /* Just sanitize referenced Device tables.  Doesn't check the values themselves. */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -8,8 +8,6 @@
 namespace Layout {
 namespace GSUB_impl {
 
-typedef hb_pair_t hb_codepoint_pair_t;
-
 template
 static void SingleSubst_serialize (hb_serialize_context_t *c,
                                    Iterator it);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh	2024-01-16 16:19:00.000000000 +0000
@@ -10,10 +10,10 @@
 template 
 struct Ligature
 {
-  protected:
+  public:
   typename Types::HBGlyphID
                 ligGlyph;               /* GlyphID of ligature to substitute */
-  HeadlessArrayOf
+  HeadlessArray16Of
                 component;              /* Array of component GlyphIDs--start
                                          * with the second  component--ordered
                                          * in writing direction */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh	2024-01-16 16:19:00.000000000 +0000
@@ -75,12 +75,69 @@
   bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
+
     unsigned int num_ligs = ligature.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+    if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4)
+#endif
+    {
+    slow:
+      for (unsigned int i = 0; i < num_ligs; i++)
+      {
+        const auto &lig = this+ligature.arrayZ[i];
+        if (lig.apply (c)) return_trace (true);
+      }
+      return_trace (false);
+    }
+
+    /* This version is optimized for speed by matching the first component
+     * of the ligature here, instead of calling into the ligation code.
+     *
+     * This is replicated in ChainRuleSet and RuleSet. */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset (c->buffer->idx);
+    skippy_iter.set_match_func (match_always, nullptr);
+    skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+    unsigned unsafe_to;
+    hb_codepoint_t first = (unsigned) -1;
+    bool matched = skippy_iter.next (&unsafe_to);
+    if (likely (matched))
+    {
+      first = c->buffer->info[skippy_iter.idx].codepoint;
+      unsafe_to = skippy_iter.idx + 1;
+
+      if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+      {
+        /* Can't use the fast path if eg. the next char is a default-ignorable
+         * or other skippable. */
+        goto slow;
+      }
+    }
+    else
+      goto slow;
+
+    bool unsafe_to_concat = false;
+
     for (unsigned int i = 0; i < num_ligs; i++)
     {
-      const auto &lig = this+ligature[i];
-      if (lig.apply (c)) return_trace (true);
+      const auto &lig = this+ligature.arrayZ[i];
+      if (unlikely (lig.component.lenP1 <= 1) ||
+          lig.component.arrayZ[0] == first)
+      {
+        if (lig.apply (c))
+        {
+          if (unsafe_to_concat)
+            c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+          return_trace (true);
+        }
+      }
+      else if (likely (lig.component.lenP1 > 1))
+        unsafe_to_concat = true;
     }
+    if (likely (unsafe_to_concat))
+      c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
 
     return_trace (false);
   }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh	2024-01-16 16:19:00.000000000 +0000
@@ -191,7 +191,6 @@
     TRACE_SERIALIZE (this);
 
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!c->serializer->check_success (out))) return_trace (false);
     if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
     if (unlikely (!c->serializer->embed (this->coverage))) return_trace (false);
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh	2024-01-16 16:19:00.000000000 +0000
@@ -53,7 +53,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
         c->buffer->message (c->font,
-                            "replaced glyph at %u (multiple subtitution)",
+                            "replaced glyph at %u (multiple substitution)",
                             c->buffer->idx - 1u);
       }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh	2024-01-16 16:19:00.000000000 +0000
@@ -57,7 +57,7 @@
 
 #ifndef HB_NO_BEYOND_64K
        if (+ glyphs
-           | hb_map_retains_sorting (hb_first)
+           | hb_map_retains_sorting (hb_second)
            | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
        {
          format += 2;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -87,19 +87,54 @@
     }
   }
 
-  void transform_points (contour_point_vector_t &points,
+  static void transform (const float (&matrix)[4],
+                         hb_array_t points)
+  {
+    if (matrix[0] != 1.f || matrix[1] != 0.f ||
+        matrix[2] != 0.f || matrix[3] != 1.f)
+      for (auto &point : points)
+        point.transform (matrix);
+  }
+
+  static void translate (const contour_point_t &trans,
+                         hb_array_t points)
+  {
+    if (HB_OPTIMIZE_SIZE_VAL)
+    {
+      if (trans.x != 0.f || trans.y != 0.f)
+        for (auto &point : points)
+          point.translate (trans);
+    }
+    else
+    {
+      if (trans.x != 0.f && trans.y != 0.f)
+        for (auto &point : points)
+          point.translate (trans);
+      else
+      {
+        if (trans.x != 0.f)
+          for (auto &point : points)
+            point.x += trans.x;
+        else if (trans.y != 0.f)
+          for (auto &point : points)
+            point.y += trans.y;
+      }
+    }
+  }
+
+  void transform_points (hb_array_t points,
                          const float (&matrix)[4],
                          const contour_point_t &trans) const
   {
     if (scaled_offsets ())
     {
-      points.translate (trans);
-      points.transform (matrix);
+      translate (trans, points);
+      transform (matrix, points);
     }
     else
     {
-      points.transform (matrix);
-      points.translate (trans);
+      transform (matrix, points);
+      translate (trans, points);
     }
   }
 
@@ -108,8 +143,8 @@
     float matrix[4];
     contour_point_t trans;
     get_transformation (matrix, trans);
-    if (unlikely (!points.resize (points.length + 1))) return false;
-    points[points.length - 1] = trans;
+    if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points
+    points.push (trans);
     return true;
   }
 
@@ -358,7 +393,7 @@
     {
       /* last 4 points in points_with_deltas are phantom points and should not be included */
       if (i >= points_with_deltas.length - 4) {
-        free (o);
+        hb_free (o);
         return false;
       }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -103,6 +103,63 @@
     }
   }
 
+  bool get_all_points_without_var (const hb_face_t *face,
+                                   contour_point_vector_t &points /* OUT */) const
+  {
+    switch (type) {
+    case SIMPLE:
+      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points)))
+        return false;
+      break;
+    case COMPOSITE:
+    {
+      for (auto &item : get_composite_iterator ())
+        if (unlikely (!item.get_points (points))) return false;
+      break;
+    }
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE:
+    {
+      for (auto &item : get_var_composite_iterator ())
+        if (unlikely (!item.get_points (points))) return false;
+      break;
+    }
+#endif
+    case EMPTY:
+      break;
+    }
+
+    /* Init phantom points */
+    if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
+    hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+    {
+      int lsb = 0;
+      int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
+                    (int) header->xMin - lsb : 0;
+      HB_UNUSED int tsb = 0;
+      int v_orig  = (int) header->yMax +
+#ifndef HB_NO_VERTICAL
+                    ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
+#else
+                    0
+#endif
+                    ;
+      unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid);
+      unsigned v_adv =
+#ifndef HB_NO_VERTICAL
+                       face->table.vmtx->get_advance_without_var_unscaled (gid)
+#else
+                       - face->get_upem ()
+#endif
+                       ;
+      phantoms[PHANTOM_LEFT].x = h_delta;
+      phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
+      phantoms[PHANTOM_TOP].y = v_orig;
+      phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
+    }
+    return true;
+  }
+
   void update_mtx (const hb_subset_plan_t *plan,
                    int xMin, int xMax,
                    int yMin, int yMax,
@@ -114,8 +171,8 @@
 
     if (type != EMPTY)
     {
-      plan->bounds_width_map.set (new_gid, xMax - xMin);
-      plan->bounds_height_map.set (new_gid, yMax - yMin);
+      plan->bounds_width_vec[new_gid] = xMax - xMin;
+      plan->bounds_height_vec[new_gid] = yMax - yMin;
     }
 
     unsigned len = all_points.length;
@@ -124,10 +181,12 @@
     float topSideY = all_points[len - 2].y;
     float bottomSideY = all_points[len - 1].y;
 
+    uint32_t hash = hb_hash (new_gid);
+
     signed hori_aw = roundf (rightSideX - leftSideX);
     if (hori_aw < 0) hori_aw = 0;
     int lsb = roundf (xMin - leftSideX);
-    plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
+    plan->hmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) hori_aw, lsb));
     //flag value should be computed using non-empty glyphs
     if (type != EMPTY && lsb != xMin)
       plan->head_maxp_info.allXMinIsLsb = false;
@@ -135,7 +194,7 @@
     signed vert_aw = roundf (topSideY - bottomSideY);
     if (vert_aw < 0) vert_aw = 0;
     int tsb = roundf (topSideY - yMax);
-    plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
+    plan->vmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) vert_aw, tsb));
   }
 
   bool compile_header_bytes (const hb_subset_plan_t *plan,
@@ -155,24 +214,28 @@
     {
       xMin = xMax = all_points[0].x;
       yMin = yMax = all_points[0].y;
+
+      unsigned count = all_points.length - 4;
+      for (unsigned i = 1; i < count; i++)
+      {
+        float x = all_points[i].x;
+        float y = all_points[i].y;
+        xMin = hb_min (xMin, x);
+        xMax = hb_max (xMax, x);
+        yMin = hb_min (yMin, y);
+        yMax = hb_max (yMax, y);
+      }
     }
 
-    for (unsigned i = 1; i < all_points.length - 4; i++)
-    {
-      float x = all_points[i].x;
-      float y = all_points[i].y;
-      xMin = hb_min (xMin, x);
-      xMax = hb_max (xMax, x);
-      yMin = hb_min (yMin, y);
-      yMax = hb_max (yMax, y);
-    }
-
-    update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points);
-
-    int rounded_xMin = roundf (xMin);
-    int rounded_xMax = roundf (xMax);
-    int rounded_yMin = roundf (yMin);
-    int rounded_yMax = roundf (yMax);
+
+    // These are destined for storage in a 16 bit field to clamp the values to
+    // fit into a 16 bit signed integer.
+    int rounded_xMin = hb_clamp (roundf (xMin), -32768.0f, 32767.0f);
+    int rounded_xMax = hb_clamp (roundf (xMax), -32768.0f, 32767.0f);
+    int rounded_yMin = hb_clamp (roundf (yMin), -32768.0f, 32767.0f);
+    int rounded_yMax = hb_clamp (roundf (yMax), -32768.0f, 32767.0f);
+
+    update_mtx (plan, rounded_xMin, rounded_xMax, rounded_yMin, rounded_yMax, all_points);
 
     if (type != EMPTY)
     {
@@ -287,6 +350,7 @@
                    bool use_my_metrics = true,
                    bool phantom_only = false,
                    hb_array_t coords = hb_array_t (),
+                   hb_map_t *current_glyphs = nullptr,
                    unsigned int depth = 0,
                    unsigned *edge_count = nullptr) const
   {
@@ -296,6 +360,10 @@
     if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false;
     (*edge_count)++;
 
+    hb_map_t current_glyphs_stack;
+    if (current_glyphs == nullptr)
+      current_glyphs = ¤t_glyphs_stack;
+
     if (head_maxp_info)
     {
       head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
@@ -305,9 +373,8 @@
       coords = hb_array (font->coords, font->num_coords);
 
     contour_point_vector_t stack_points;
-    bool inplace = type == SIMPLE && all_points.length == 0;
-    /* Load into all_points if it's empty, as an optimization. */
-    contour_point_vector_t &points = inplace ? all_points : stack_points;
+    contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points;
+    unsigned old_length = points.length;
 
     switch (type) {
     case SIMPLE:
@@ -315,7 +382,7 @@
         head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours);
       if (depth > 0 && composite_contours)
         *composite_contours += (unsigned) header->numberOfContours;
-      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
+      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (all_points, phantom_only)))
         return false;
       break;
     case COMPOSITE:
@@ -329,6 +396,7 @@
     {
       for (auto &item : get_var_composite_iterator ())
         if (unlikely (!item.get_points (points))) return false;
+      break;
     }
 #endif
     case EMPTY:
@@ -365,9 +433,11 @@
     }
 
 #ifndef HB_NO_VAR
-    glyf_accelerator.gvar->apply_deltas_to_points (gid,
-                                                   coords,
-                                                   points.as_array ());
+    if (coords)
+      glyf_accelerator.gvar->apply_deltas_to_points (gid,
+                                                     coords,
+                                                     points.as_array ().sub_array (old_length),
+                                                     phantom_only && type == SIMPLE);
 #endif
 
     // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
@@ -375,27 +445,33 @@
     if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
     {
       if (unlikely (!points_with_deltas->resize (points.length))) return false;
-      points_with_deltas->copy_vector (points);
+      *points_with_deltas = points;
     }
 
     switch (type) {
     case SIMPLE:
       if (depth == 0 && head_maxp_info)
-        head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, points.length - 4);
-      if (!inplace)
-        all_points.extend (points.as_array ());
+        head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4);
       break;
     case COMPOSITE:
     {
-      contour_point_vector_t comp_points;
       unsigned int comp_index = 0;
       for (auto &item : get_composite_iterator ())
       {
-        comp_points.reset ();
-        if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+        hb_codepoint_t item_gid = item.get_gid ();
+
+        if (unlikely (current_glyphs->has (item_gid)))
+          continue;
+
+        current_glyphs->add (item_gid);
+
+        unsigned old_count = all_points.length;
+
+        if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
+                      !glyf_accelerator.glyph_for_gid (item_gid)
                                        .get_points (font,
                                                     glyf_accelerator,
-                                                    comp_points,
+                                                    all_points,
                                                     points_with_deltas,
                                                     head_maxp_info,
                                                     composite_contours,
@@ -403,23 +479,32 @@
                                                     use_my_metrics,
                                                     phantom_only,
                                                     coords,
+                                                    current_glyphs,
                                                     depth + 1,
                                                     edge_count)))
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
+
+        auto comp_points = all_points.as_array ().sub_array (old_count);
 
         /* Copy phantom points from component if USE_MY_METRICS flag set */
         if (use_my_metrics && item.is_use_my_metrics ())
           for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
             phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
 
-        float matrix[4];
-        contour_point_t default_trans;
-        item.get_transformation (matrix, default_trans);
+        if (comp_points) // Empty in case of phantom_only
+        {
+          float matrix[4];
+          contour_point_t default_trans;
+          item.get_transformation (matrix, default_trans);
 
-        /* Apply component transformation & translation (with deltas applied) */
-        item.transform_points (comp_points, matrix, points[comp_index]);
+          /* Apply component transformation & translation (with deltas applied) */
+          item.transform_points (comp_points, matrix, points[comp_index]);
+        }
 
-        if (item.is_anchored ())
+        if (item.is_anchored () && !phantom_only)
         {
           unsigned int p1, p2;
           item.get_anchor_points (p1, p2);
@@ -429,16 +514,20 @@
             delta.init (all_points[p1].x - comp_points[p2].x,
                         all_points[p1].y - comp_points[p2].y);
 
-            comp_points.translate (delta);
+            item.translate (delta, comp_points);
           }
         }
 
-        all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+        all_points.resize (all_points.length - PHANTOM_COUNT);
 
         if (all_points.length > HB_GLYF_MAX_POINTS)
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
 
         comp_index++;
+        current_glyphs->del (item_gid);
       }
 
       if (head_maxp_info && depth == 0)
@@ -453,26 +542,37 @@
 #ifndef HB_NO_VAR_COMPOSITES
     case VAR_COMPOSITE:
     {
-      contour_point_vector_t comp_points;
       hb_array_t points_left = points.as_array ();
       for (auto &item : get_var_composite_iterator ())
       {
+        hb_codepoint_t item_gid = item.get_gid ();
+
+        if (unlikely (current_glyphs->has (item_gid)))
+          continue;
+
+        current_glyphs->add (item_gid);
+
         unsigned item_num_points = item.get_num_points ();
         hb_array_t record_points = points_left.sub_array (0, item_num_points);
-
-        comp_points.reset ();
+        assert (record_points.length == item_num_points);
 
         auto component_coords = coords;
-        if (item.is_reset_unspecified_axes ())
+        /* Copying coords is expensive; so we have put an arbitrary
+         * limit on the max number of coords for now. */
+        if (item.is_reset_unspecified_axes () ||
+            coords.length > HB_GLYF_VAR_COMPOSITE_MAX_AXES)
           component_coords = hb_array ();
 
         coord_setter_t coord_setter (component_coords);
         item.set_variations (coord_setter, record_points);
 
-        if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+        unsigned old_count = all_points.length;
+
+        if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
+                      !glyf_accelerator.glyph_for_gid (item_gid)
                                        .get_points (font,
                                                     glyf_accelerator,
-                                                    comp_points,
+                                                    all_points,
                                                     points_with_deltas,
                                                     head_maxp_info,
                                                     nullptr,
@@ -480,24 +580,36 @@
                                                     use_my_metrics,
                                                     phantom_only,
                                                     coord_setter.get_coords (),
+                                                    current_glyphs,
                                                     depth + 1,
                                                     edge_count)))
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
+
+        auto comp_points = all_points.as_array ().sub_array (old_count);
 
         /* Apply component transformation */
-        item.transform_points (record_points, comp_points);
+        if (comp_points) // Empty in case of phantom_only
+          item.transform_points (record_points, comp_points);
 
         /* Copy phantom points from component if USE_MY_METRICS flag set */
         if (use_my_metrics && item.is_use_my_metrics ())
           for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
             phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
 
-        all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+        all_points.resize (all_points.length - PHANTOM_COUNT);
 
         if (all_points.length > HB_GLYF_MAX_POINTS)
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
 
         points_left += item_num_points;
+
+        current_glyphs->del (item_gid);
       }
       all_points.extend (phantoms);
     } break;
@@ -512,9 +624,10 @@
       /* Undocumented rasterizer behavior:
        * Shift points horizontally by the updated left side bearing
        */
-      contour_point_t delta;
-      delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
-      if (delta.x) all_points.translate (delta);
+      int v = -phantoms[PHANTOM_LEFT].x;
+      if (v)
+        for (auto &point : all_points)
+          point.x += v;
     }
 
     return !all_points.in_error ();
@@ -545,10 +658,11 @@
     int num_contours = header->numberOfContours;
     if (unlikely (num_contours == 0)) type = EMPTY;
     else if (num_contours > 0) type = SIMPLE;
+    else if (num_contours == -1) type = COMPOSITE;
 #ifndef HB_NO_VAR_COMPOSITES
     else if (num_contours == -2) type = VAR_COMPOSITE;
 #endif
-    else type = COMPOSITE; /* negative numbers */
+    else type = EMPTY; // Spec deviation; Spec says COMPOSITE, but not seen in the wild.
   }
 
   protected:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -124,7 +124,7 @@
   }
 
   static bool read_flags (const HBUINT8 *&p /* IN/OUT */,
-                          contour_point_vector_t &points_ /* IN/OUT */,
+                          hb_array_t points_ /* IN/OUT */,
                           const HBUINT8 *end)
   {
     unsigned count = points_.length;
@@ -146,7 +146,7 @@
   }
 
   static bool read_points (const HBUINT8 *&p /* IN/OUT */,
-                           contour_point_vector_t &points_ /* IN/OUT */,
+                           hb_array_t points_ /* IN/OUT */,
                            const HBUINT8 *end,
                            float contour_point_t::*m,
                            const simple_glyph_flag_t short_flag,
@@ -154,10 +154,9 @@
   {
     int v = 0;
 
-    unsigned count = points_.length;
-    for (unsigned i = 0; i < count; i++)
+    for (auto &point : points_)
     {
-      unsigned flag = points_[i].flag;
+      unsigned flag = point.flag;
       if (flag & short_flag)
       {
         if (unlikely (p + 1 > end)) return false;
@@ -175,23 +174,27 @@
           p += HBINT16::static_size;
         }
       }
-      points_.arrayZ[i].*m = v;
+      point.*m = v;
     }
     return true;
   }
 
-  bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+  bool get_contour_points (contour_point_vector_t &points /* OUT */,
                            bool phantom_only = false) const
   {
     const HBUINT16 *endPtsOfContours = &StructAfter (header);
     int num_contours = header.numberOfContours;
-    assert (num_contours);
+    assert (num_contours > 0);
     /* One extra item at the end, for the instruction-count below. */
     if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours]))) return false;
     unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
 
-    points_.alloc (num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
-    if (!points_.resize (num_points)) return false;
+    unsigned old_length = points.length;
+    points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
+    if (unlikely (!points.resize (points.length + num_points, false))) return false;
+    auto points_ = points.as_array ().sub_array (old_length);
+    if (!phantom_only)
+      hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points);
     if (phantom_only) return true;
 
     for (int i = 0; i < num_contours; i++)
@@ -214,7 +217,7 @@
   }
 
   static void encode_coord (int value,
-                            uint8_t &flag,
+                            unsigned &flag,
                             const simple_glyph_flag_t short_flag,
                             const simple_glyph_flag_t same_flag,
                             hb_vector_t &coords /* OUT */)
@@ -239,9 +242,9 @@
     }
   }
 
-  static void encode_flag (uint8_t &flag,
-                           uint8_t &repeat,
-                           uint8_t lastflag,
+  static void encode_flag (unsigned flag,
+                           unsigned &repeat,
+                           unsigned lastflag,
                            hb_vector_t &flags /* OUT */)
   {
     if (flag == lastflag && repeat != 255)
@@ -262,7 +265,7 @@
     else
     {
       repeat = 0;
-      flags.push (flag);
+      flags.arrayZ[flags.length++] = flag;
     }
   }
 
@@ -282,13 +285,13 @@
     if (unlikely (!x_coords.alloc (2*num_points, true))) return false;
     if (unlikely (!y_coords.alloc (2*num_points, true))) return false;
 
-    uint8_t lastflag = 255, repeat = 0;
+    unsigned lastflag = 255, repeat = 0;
     int prev_x = 0, prev_y = 0;
 
     for (unsigned i = 0; i < num_points; i++)
     {
-      uint8_t flag = all_points.arrayZ[i].flag;
-      flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
+      unsigned flag = all_points.arrayZ[i].flag;
+      flag &= FLAG_ON_CURVE | FLAG_OVERLAP_SIMPLE | FLAG_CUBIC;
 
       int cur_x = roundf (all_points.arrayZ[i].x);
       int cur_y = roundf (all_points.arrayZ[i].y);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -22,7 +22,7 @@
 
   bool serialize (hb_serialize_context_t *c,
                   bool use_short_loca,
-                  const hb_subset_plan_t *plan)
+                  const hb_subset_plan_t *plan) const
   {
     TRACE_SERIALIZE (this);
 
@@ -40,7 +40,7 @@
     pad = 0;
     while (pad_length > 0)
     {
-      c->embed (pad);
+      (void) c->embed (pad);
       pad_length--;
     }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -36,24 +36,21 @@
 
   unsigned int get_size () const
   {
+    unsigned fl = flags;
     unsigned int size = min_size;
 
-    unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
+    unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
     size += numAxes * axis_width;
 
-    // gid
-    size += 2;
-    if (flags & GID_IS_24BIT)           size += 1;
-
-    if (flags & HAVE_TRANSLATE_X)       size += 2;
-    if (flags & HAVE_TRANSLATE_Y)       size += 2;
-    if (flags & HAVE_ROTATION)          size += 2;
-    if (flags & HAVE_SCALE_X)           size += 2;
-    if (flags & HAVE_SCALE_Y)           size += 2;
-    if (flags & HAVE_SKEW_X)            size += 2;
-    if (flags & HAVE_SKEW_Y)            size += 2;
-    if (flags & HAVE_TCENTER_X)         size += 2;
-    if (flags & HAVE_TCENTER_Y)         size += 2;
+    if (fl & GID_IS_24BIT)      size += 1;
+
+    // 2 bytes each for the following flags
+    fl = fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y |
+               HAVE_ROTATION |
+               HAVE_SCALE_X | HAVE_SCALE_Y |
+               HAVE_SKEW_X | HAVE_SKEW_Y |
+               HAVE_TCENTER_X | HAVE_TCENTER_Y);
+    size += hb_popcount (fl) * 2;
 
     return size;
   }
@@ -66,17 +63,17 @@
   hb_codepoint_t get_gid () const
   {
     if (flags & GID_IS_24BIT)
-      return StructAfter (numAxes);
+      return * (const HBGlyphID24 *) &pad;
     else
-      return StructAfter (numAxes);
+      return * (const HBGlyphID16 *) &pad;
   }
 
   void set_gid (hb_codepoint_t gid)
   {
     if (flags & GID_IS_24BIT)
-      StructAfter (numAxes) = gid;
+      * (HBGlyphID24 *) &pad = gid;
     else
-      StructAfter (numAxes) = gid;
+      * (HBGlyphID16 *) &pad = gid;
   }
 
   unsigned get_numAxes () const
@@ -86,26 +83,44 @@
 
   unsigned get_num_points () const
   {
+    unsigned fl = flags;
     unsigned num = 0;
-    if (flags & AXES_HAVE_VARIATION)                    num += numAxes;
-    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))  num++;
-    if (flags & HAVE_ROTATION)                          num++;
-    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))          num++;
-    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))            num++;
-    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))      num++;
+    if (fl & AXES_HAVE_VARIATION)                       num += numAxes;
+
+    /* Hopefully faster code, relying on the value of the flags. */
+    fl = (((fl & (HAVE_TRANSLATE_Y | HAVE_SCALE_Y | HAVE_SKEW_Y | HAVE_TCENTER_Y)) >> 1) | fl) &
+         (HAVE_TRANSLATE_X | HAVE_ROTATION | HAVE_SCALE_X | HAVE_SKEW_X | HAVE_TCENTER_X);
+    num += hb_popcount (fl);
+    return num;
+
+    /* Slower but more readable code. */
+    if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))     num++;
+    if (fl & HAVE_ROTATION)                             num++;
+    if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))             num++;
+    if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))               num++;
+    if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))         num++;
     return num;
   }
 
-  void transform_points (hb_array_t record_points,
-                         contour_point_vector_t &points) const
+  void transform_points (hb_array_t record_points,
+                         hb_array_t points) const
   {
     float matrix[4];
     contour_point_t trans;
 
-    get_transformation_from_points (record_points, matrix, trans);
+    get_transformation_from_points (record_points.arrayZ, matrix, trans);
+
+    auto arrayZ = points.arrayZ;
+    unsigned count = points.length;
+
+    if (matrix[0] != 1.f || matrix[1] != 0.f ||
+        matrix[2] != 0.f || matrix[3] != 1.f)
+      for (unsigned i = 0; i < count; i++)
+        arrayZ[i].transform (matrix);
 
-    points.transform (matrix);
-    points.translate (trans);
+    if (trans.x != 0.f || trans.y != 0.f)
+      for (unsigned i = 0; i < count; i++)
+        arrayZ[i].translate (trans);
   }
 
   static inline void transform (float (&matrix)[4], contour_point_t &trans,
@@ -136,26 +151,41 @@
   static void translate (float (&matrix)[4], contour_point_t &trans,
                          float translateX, float translateY)
   {
-    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213
-    float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY};
-    transform (matrix, trans, other);
+    if (!translateX && !translateY)
+      return;
+
+    trans.x += matrix[0] * translateX + matrix[2] * translateY;
+    trans.y += matrix[1] * translateX + matrix[3] * translateY;
   }
 
   static void scale (float (&matrix)[4], contour_point_t &trans,
                      float scaleX, float scaleY)
   {
-    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224
-    float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f};
-    transform (matrix, trans, other);
+    if (scaleX == 1.f && scaleY == 1.f)
+      return;
+
+    matrix[0] *= scaleX;
+    matrix[1] *= scaleX;
+    matrix[2] *= scaleY;
+    matrix[3] *= scaleY;
   }
 
   static void rotate (float (&matrix)[4], contour_point_t &trans,
                       float rotation)
   {
+    if (!rotation)
+      return;
+
     // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
     rotation = rotation * HB_PI;
-    float c = cosf (rotation);
-    float s = sinf (rotation);
+    float c;
+    float s;
+#ifdef HAVE_SINCOSF
+    sincosf (rotation, &s, &c);
+#else
+    c = cosf (rotation);
+    s = sinf (rotation);
+#endif
     float other[6] = {c, s, -s, c, 0.f, 0.f};
     transform (matrix, trans, other);
   }
@@ -163,101 +193,100 @@
   static void skew (float (&matrix)[4], contour_point_t &trans,
                     float skewX, float skewY)
   {
+    if (!skewX && !skewY)
+      return;
+
     // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
     skewX = skewX * HB_PI;
     skewY = skewY * HB_PI;
-    float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
+    float other[6] = {1.f,
+                      skewY ? tanf (skewY) : 0.f,
+                      skewX ? tanf (skewX) : 0.f,
+                      1.f,
+                      0.f, 0.f};
     transform (matrix, trans, other);
   }
 
   bool get_points (contour_point_vector_t &points) const
   {
-    float translateX = 0.f;
-    float translateY = 0.f;
-    float rotation = 0.f;
-    float scaleX = 1.f * (1 << 10);
-    float scaleY = 1.f * (1 << 10);
-    float skewX = 0.f;
-    float skewY = 0.f;
-    float tCenterX = 0.f;
-    float tCenterY = 0.f;
-
     unsigned num_points = get_num_points ();
 
-    if (unlikely (!points.resize (points.length + num_points))) return false;
-
-    unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
-    unsigned axes_size = numAxes * axis_width;
+    points.alloc (points.length + num_points + 4); // For phantom points
+    if (unlikely (!points.resize (points.length + num_points, false))) return false;
+    contour_point_t *rec_points = points.arrayZ + (points.length - num_points);
+    hb_memset (rec_points, 0, num_points * sizeof (rec_points[0]));
+
+    unsigned fl = flags;
+
+    unsigned num_axes = numAxes;
+    unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+    unsigned axes_size = num_axes * axis_width;
 
     const F2DOT14 *q = (const F2DOT14 *) (axes_size +
-                                          (flags & GID_IS_24BIT ? 3 : 2) +
-                                          &StructAfter (numAxes));
-
-    hb_array_t rec_points = points.as_array ().sub_array (points.length - num_points);
+                                          (fl & GID_IS_24BIT ? 3 : 2) +
+                                          (const HBUINT8 *) &pad);
 
-    unsigned count = numAxes;
-    if (flags & AXES_HAVE_VARIATION)
+    unsigned count = num_axes;
+    if (fl & AXES_HAVE_VARIATION)
     {
       for (unsigned i = 0; i < count; i++)
-        rec_points[i].x = q++->to_int ();
-      rec_points += count;
+        rec_points++->x = q++->to_int ();
     }
     else
       q += count;
 
     const HBUINT16 *p = (const HBUINT16 *) q;
 
-    if (flags & HAVE_TRANSLATE_X)       translateX = * (const FWORD *) p++;
-    if (flags & HAVE_TRANSLATE_Y)       translateY = * (const FWORD *) p++;
-    if (flags & HAVE_ROTATION)          rotation = ((const F4DOT12 *) p++)->to_int ();
-    if (flags & HAVE_SCALE_X)           scaleX = ((const F6DOT10 *) p++)->to_int ();
-    if (flags & HAVE_SCALE_Y)           scaleY = ((const F6DOT10 *) p++)->to_int ();
-    if (flags & HAVE_SKEW_X)            skewX = ((const F4DOT12 *) p++)->to_int ();
-    if (flags & HAVE_SKEW_Y)            skewY = ((const F4DOT12 *) p++)->to_int ();
-    if (flags & HAVE_TCENTER_X)         tCenterX = * (const FWORD *) p++;
-    if (flags & HAVE_TCENTER_Y)         tCenterY = * (const FWORD *) p++;
-
-    if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y))
-      scaleY = scaleX;
-
-    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+    if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
     {
-      rec_points[0].x = translateX;
-      rec_points[0].y = translateY;
+      int translateX = (fl & HAVE_TRANSLATE_X) ? * (const FWORD *) p++ : 0;
+      int translateY = (fl & HAVE_TRANSLATE_Y) ? * (const FWORD *) p++ : 0;
+      rec_points->x = translateX;
+      rec_points->y = translateY;
       rec_points++;
     }
-    if (flags & HAVE_ROTATION)
+    if (fl & HAVE_ROTATION)
     {
-      rec_points[0].x = rotation;
+      int rotation = (fl & HAVE_ROTATION) ? ((const F4DOT12 *) p++)->to_int () : 0;
+      rec_points->x = rotation;
       rec_points++;
     }
-    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+    if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))
     {
-      rec_points[0].x = scaleX;
-      rec_points[0].y = scaleY;
+      int scaleX = (fl & HAVE_SCALE_X) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10;
+      int scaleY = (fl & HAVE_SCALE_Y) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10;
+      if ((fl & UNIFORM_SCALE) && !(fl & HAVE_SCALE_Y))
+        scaleY = scaleX;
+      rec_points->x = scaleX;
+      rec_points->y = scaleY;
       rec_points++;
     }
-    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+    if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))
     {
-      rec_points[0].x = skewX;
-      rec_points[0].y = skewY;
+      int skewX = (fl & HAVE_SKEW_X) ? ((const F4DOT12 *) p++)->to_int () : 0;
+      int skewY = (fl & HAVE_SKEW_Y) ? ((const F4DOT12 *) p++)->to_int () : 0;
+      rec_points->x = skewX;
+      rec_points->y = skewY;
       rec_points++;
     }
-    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+    if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
     {
-      rec_points[0].x = tCenterX;
-      rec_points[0].y = tCenterY;
+      int tCenterX = (fl & HAVE_TCENTER_X) ? * (const FWORD *) p++ : 0;
+      int tCenterY = (fl & HAVE_TCENTER_Y) ? * (const FWORD *) p++ : 0;
+      rec_points->x = tCenterX;
+      rec_points->y = tCenterY;
       rec_points++;
     }
-    assert (!rec_points);
 
     return true;
   }
 
-  void get_transformation_from_points (hb_array_t rec_points,
+  void get_transformation_from_points (const contour_point_t *rec_points,
                                        float (&matrix)[4], contour_point_t &trans) const
   {
-    if (flags & AXES_HAVE_VARIATION)
+    unsigned fl = flags;
+
+    if (fl & AXES_HAVE_VARIATION)
       rec_points += numAxes;
 
     matrix[0] = matrix[3] = 1.f;
@@ -274,36 +303,35 @@
     float tCenterX = 0.f;
     float tCenterY = 0.f;
 
-    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+    if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
     {
-      translateX = rec_points[0].x;
-      translateY = rec_points[0].y;
+      translateX = rec_points->x;
+      translateY = rec_points->y;
       rec_points++;
     }
-    if (flags & HAVE_ROTATION)
+    if (fl & HAVE_ROTATION)
     {
-      rotation = rec_points[0].x / (1 << 12);
+      rotation = rec_points->x / (1 << 12);
       rec_points++;
     }
-    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+    if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))
     {
-      scaleX = rec_points[0].x / (1 << 10);
-      scaleY = rec_points[0].y / (1 << 10);
+      scaleX = rec_points->x / (1 << 10);
+      scaleY = rec_points->y / (1 << 10);
       rec_points++;
     }
-    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+    if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))
     {
-      skewX = rec_points[0].x / (1 << 12);
-      skewY = rec_points[0].y / (1 << 12);
+      skewX = rec_points->x / (1 << 12);
+      skewY = rec_points->y / (1 << 12);
       rec_points++;
     }
-    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+    if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
     {
-      tCenterX = rec_points[0].x;
-      tCenterY = rec_points[0].y;
+      tCenterX = rec_points->x;
+      tCenterY = rec_points->y;
       rec_points++;
     }
-    assert (!rec_points);
 
     translate (matrix, trans, translateX + tCenterX, translateY + tCenterY);
     rotate (matrix, trans, rotation);
@@ -317,18 +345,19 @@
   {
     bool have_variations = flags & AXES_HAVE_VARIATION;
     unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+    unsigned num_axes = numAxes;
 
     const HBUINT8  *p = (const HBUINT8 *)  (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
     const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
 
-    const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
+    const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + num_axes) : (HBUINT8 *) (q + num_axes)));
 
-    unsigned count = numAxes;
+    unsigned count = num_axes;
     for (unsigned i = 0; i < count; i++)
     {
       unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++;
 
-      signed v = have_variations ? rec_points[i].x : a++->to_int ();
+      signed v = have_variations ? rec_points.arrayZ[i].x : a++->to_int ();
 
       v = hb_clamp (v, -(1<<14), (1<<14));
       setter[axis_index] = v;
@@ -338,8 +367,9 @@
   protected:
   HBUINT16      flags;
   HBUINT8       numAxes;
+  HBUINT16      pad;
   public:
-  DEFINE_SIZE_MIN (3);
+  DEFINE_SIZE_MIN (5);
 };
 
 using var_composite_iter_t = composite_iter_tmpl;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh	2024-01-16 16:19:00.000000000 +0000
@@ -16,6 +16,8 @@
 
   int& operator [] (unsigned idx)
   {
+    if (unlikely (idx >= HB_GLYF_VAR_COMPOSITE_MAX_AXES))
+      return Crap(int);
     if (coords.length < idx + 1)
       coords.resize (idx + 1);
     return coords[idx];
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh	2024-01-16 16:19:00.000000000 +0000
@@ -12,24 +12,44 @@
 namespace glyf_impl {
 
 
-template
+template
 static void
-_write_loca (IteratorIn&& it, bool short_offsets, IteratorOut&& dest)
+_write_loca (IteratorIn&& it,
+             const hb_sorted_vector_t new_to_old_gid_list,
+             bool short_offsets,
+             TypeOut *dest,
+             unsigned num_offsets)
 {
   unsigned right_shift = short_offsets ? 1 : 0;
-  unsigned int offset = 0;
-  dest << 0;
-  + it
-  | hb_map ([=, &offset] (unsigned int padded_size)
-            {
-              offset += padded_size;
-              DEBUG_MSG (SUBSET, nullptr, "loca entry offset %u", offset);
-              return offset >> right_shift;
-            })
-  | hb_sink (dest)
-  ;
+  unsigned offset = 0;
+  TypeOut value;
+  value = 0;
+  *dest++ = value;
+  hb_codepoint_t last = 0;
+  for (auto _ : new_to_old_gid_list)
+  {
+    hb_codepoint_t gid = _.first;
+    for (; last < gid; last++)
+    {
+      DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u", offset);
+      *dest++ = value;
+    }
+
+    unsigned padded_size = *it++;
+    offset += padded_size;
+    DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u", gid, offset, padded_size);
+    value = offset >> right_shift;
+    *dest++ = value;
+
+    last++; // Skip over gid
+  }
+  unsigned num_glyphs = num_offsets - 1;
+  for (; last < num_glyphs; last++)
+  {
+    DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u", offset);
+    *dest++ = value;
+  }
 }
 
 static bool
@@ -67,11 +87,14 @@
 template
 static bool
-_add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
+_add_loca_and_head (hb_subset_context_t *c,
+                    Iterator padded_offsets,
+                    bool use_short_loca)
 {
-  unsigned num_offsets = padded_offsets.len () + 1;
+  unsigned num_offsets = c->plan->num_output_glyphs () + 1;
   unsigned entry_size = use_short_loca ? 2 : 4;
-  char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
+
+  char *loca_prime_data = (char *) hb_malloc (entry_size * num_offsets);
 
   if (unlikely (!loca_prime_data)) return false;
 
@@ -79,9 +102,9 @@
              entry_size, num_offsets, entry_size * num_offsets);
 
   if (use_short_loca)
-    _write_loca (padded_offsets, true, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
+    _write_loca (padded_offsets, c->plan->new_to_old_gid_list, true, (HBUINT16 *) loca_prime_data, num_offsets);
   else
-    _write_loca (padded_offsets, false, hb_array ((HBUINT32 *) loca_prime_data, num_offsets));
+    _write_loca (padded_offsets, c->plan->new_to_old_gid_list, false, (HBUINT32 *) loca_prime_data, num_offsets);
 
   hb_blob_t *loca_blob = hb_blob_create (loca_prime_data,
                                          entry_size * num_offsets,
@@ -89,8 +112,8 @@
                                          loca_prime_data,
                                          hb_free);
 
-  bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
-             && _add_head_and_set_loca_version (plan, use_short_loca);
+  bool result = c->plan->add_table (HB_OT_TAG_loca, loca_blob)
+             && _add_head_and_set_loca_version (c->plan, use_short_loca);
 
   hb_blob_destroy (loca_blob);
   return result;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh	2024-01-16 16:19:00.000000000 +0000
@@ -85,75 +85,72 @@
       return_trace (false);
     }
 
-    glyf *glyf_prime = c->serializer->start_embed  ();
-    if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
-
     hb_font_t *font = nullptr;
     if (c->plan->normalized_coords)
     {
       font = _create_font_for_instancing (c->plan);
-      if (unlikely (!font)) return false;
+      if (unlikely (!font))
+        return_trace (false);
     }
 
     hb_vector_t padded_offsets;
-    unsigned num_glyphs = c->plan->num_output_glyphs ();
-    if (unlikely (!padded_offsets.resize (num_glyphs)))
-    {
-      hb_font_destroy (font);
-      return false;
-    }
+    if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true)))
+      return_trace (false);
 
     hb_vector_t glyphs;
     if (!_populate_subset_glyphs (c->plan, font, glyphs))
     {
       hb_font_destroy (font);
-      return false;
+      return_trace (false);
     }
 
     if (font)
       hb_font_destroy (font);
 
     unsigned max_offset = 0;
-    for (unsigned i = 0; i < num_glyphs; i++)
+    for (auto &g : glyphs)
     {
-      padded_offsets[i] = glyphs[i].padded_size ();
-      max_offset += padded_offsets[i];
+      unsigned size = g.padded_size ();
+      padded_offsets.push (size);
+      max_offset += size;
     }
 
     bool use_short_loca = false;
     if (likely (!c->plan->force_long_loca))
       use_short_loca = max_offset < 0x1FFFF;
 
-    if (!use_short_loca) {
-      for (unsigned i = 0; i < num_glyphs; i++)
-        padded_offsets[i] = glyphs[i].length ();
+    if (!use_short_loca)
+    {
+      padded_offsets.resize (0);
+      for (auto &g : glyphs)
+        padded_offsets.push (g.length ());
     }
 
-    bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan);
+    auto *glyf_prime = c->serializer->start_embed  ();
+    bool result = glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
     if (c->plan->normalized_coords && !c->plan->pinned_at_default)
       _free_compiled_subset_glyphs (glyphs);
 
-    if (!result) return false;
-
-    if (unlikely (c->serializer->in_error ())) return_trace (false);
+    if (unlikely (!c->serializer->check_success (glyf_impl::_add_loca_and_head (c,
+                                                 padded_offsets.iter (),
+                                                 use_short_loca))))
+      return_trace (false);
 
-    return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
-                                                                               padded_offsets.iter (),
-                                                                               use_short_loca)));
+    return result;
   }
 
   bool
   _populate_subset_glyphs (const hb_subset_plan_t   *plan,
                            hb_font_t                *font,
-                           hb_vector_t &glyphs /* OUT */) const;
+                           hb_vector_t& glyphs /* OUT */) const;
 
   hb_font_t *
   _create_font_for_instancing (const hb_subset_plan_t *plan) const;
 
   void _free_compiled_subset_glyphs (hb_vector_t &glyphs) const
   {
-    for (unsigned i = 0; i < glyphs.length; i++)
-      glyphs[i].free_compiled_bytes ();
+    for (auto &g : glyphs)
+      g.free_compiled_bytes ();
   }
 
   protected:
@@ -222,13 +219,14 @@
     if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only)))
       return false;
 
+    unsigned count = all_points.length;
+    assert (count >= glyf_impl::PHANTOM_COUNT);
+    count -= glyf_impl::PHANTOM_COUNT;
+
     if (consumer.is_consuming_contour_points ())
     {
-      unsigned count = all_points.length;
-      assert (count >= glyf_impl::PHANTOM_COUNT);
-      count -= glyf_impl::PHANTOM_COUNT;
-      for (unsigned point_index = 0; point_index < count; point_index++)
-        consumer.consume_point (all_points[point_index]);
+      for (auto &point : all_points.as_array ().sub_array (0, count))
+        consumer.consume_point (point);
       consumer.points_end ();
     }
 
@@ -236,7 +234,7 @@
     contour_point_t *phantoms = consumer.get_phantoms_sink ();
     if (phantoms)
       for (unsigned i = 0; i < glyf_impl::PHANTOM_COUNT; ++i)
-        phantoms[i] = all_points[all_points.length - glyf_impl::PHANTOM_COUNT + i];
+        phantoms[i] = all_points.arrayZ[count + i];
 
     return true;
   }
@@ -299,6 +297,7 @@
       if (extents) bounds = contour_bounds_t ();
     }
 
+    HB_ALWAYS_INLINE
     void consume_point (const contour_point_t &point) { bounds.add (point); }
     void points_end () { bounds.get_extents (font, extents, scaled); }
 
@@ -431,16 +430,17 @@
                                hb_vector_t& glyphs /* OUT */) const
 {
   OT::glyf_accelerator_t glyf (plan->source);
-  unsigned num_glyphs = plan->num_output_glyphs ();
-  if (!glyphs.resize (num_glyphs)) return false;
+  if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false;
 
-  for (auto p : plan->glyph_map->iter ())
+  for (const auto &pair : plan->new_to_old_gid_list)
   {
-    unsigned new_gid = p.second;
-    glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid];
-    subset_glyph.old_gid = p.first;
+    hb_codepoint_t new_gid = pair.first;
+    hb_codepoint_t old_gid = pair.second;
+    glyf_impl::SubsetGlyph *p = glyphs.push ();
+    glyf_impl::SubsetGlyph& subset_glyph = *p;
+    subset_glyph.old_gid = old_gid;
 
-    if (unlikely (new_gid == 0 &&
+    if (unlikely (old_gid == 0 && new_gid == 0 &&
                   !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
                   !plan->normalized_coords)
       subset_glyph.source_glyph = glyf_impl::Glyph ();
@@ -487,7 +487,7 @@
   {
     hb_variation_t var;
     var.tag = _.first;
-    var.value = _.second;
+    var.value = _.second.middle;
     vars.push (var);
   }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh	2024-01-16 16:19:00.000000000 +0000
@@ -21,19 +21,15 @@
     operator bool () const { return has_data; }
 
     bool has_data = false;
-    float x = 0.;
-    float y = 0.;
+    float x;
+    float y;
 
-    optional_point_t lerp (optional_point_t p, float t)
-    { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
+    optional_point_t mid (optional_point_t p)
+    { return optional_point_t ((x + p.x) * 0.5f, (y + p.y) * 0.5f); }
   } first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2;
 
-  path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
-  {
-    font = font_;
-    draw_session = &draw_session_;
-    first_oncurve = first_offcurve = first_offcurve2 = last_offcurve = last_offcurve2 = optional_point_t ();
-  }
+  path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) :
+    font (font_), draw_session (&draw_session_) {}
 
   /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
      See also:
@@ -41,6 +37,7 @@
      * https://stackoverflow.com/a/20772557
      *
      * Cubic support added. */
+  HB_ALWAYS_INLINE
   void consume_point (const contour_point_t &point)
   {
     bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
@@ -50,7 +47,7 @@
     bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
 #endif
     optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
-    if (!first_oncurve)
+    if (unlikely (!first_oncurve))
     {
       if (is_on_curve)
       {
@@ -66,7 +63,7 @@
         }
         else if (first_offcurve)
         {
-          optional_point_t mid = first_offcurve.lerp (p, .5f);
+          optional_point_t mid = first_offcurve.mid (p);
           first_oncurve = mid;
           last_offcurve = p;
           draw_session->move_to (mid.x, mid.y);
@@ -102,7 +99,7 @@
           }
           else
           {
-            optional_point_t mid = last_offcurve.lerp (p, .5f);
+            optional_point_t mid = last_offcurve.mid (p);
 
             if (is_cubic)
             {
@@ -127,13 +124,13 @@
       }
     }
 
-    if (point.is_end_point)
+    if (unlikely (point.is_end_point))
     {
       if (first_offcurve && last_offcurve)
       {
-        optional_point_t mid = last_offcurve.lerp (first_offcurve2 ?
-                                                   first_offcurve2 :
-                                                   first_offcurve, .5f);
+        optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
+                                                  first_offcurve2 :
+                                                  first_offcurve);
         if (last_offcurve2)
           draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
                                   last_offcurve.x, last_offcurve.y,
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh	2024-01-16 16:19:00.000000000 +0000
@@ -359,7 +359,7 @@
       record.nameID = ids.name_id;
       record.length = 0; // handled in NameRecord copy()
       record.offset = 0;
-      memcpy (name_records, &record, NameRecord::static_size);
+      hb_memcpy (name_records, &record, NameRecord::static_size);
       name_records++;
     }
 #endif
@@ -384,10 +384,7 @@
 
   bool subset (hb_subset_context_t *c) const
   {
-    TRACE_SUBSET (this);
-
-    name *name_prime = c->serializer->start_embed ();
-    if (unlikely (!name_prime)) return_trace (false);
+    auto *name_prime = c->serializer->start_embed ();
 
 #ifdef HB_EXPERIMENTAL_API
     const hb_hashmap_t *name_table_overrides =
@@ -436,7 +433,7 @@
     if (!name_table_overrides->is_empty ())
     {
       if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population (), true)))
-        return_trace (false);
+        return false;
       for (const auto& record_ids : name_table_overrides->keys ())
       {
         if (name_table_overrides->get (record_ids).length == 0)
@@ -448,13 +445,13 @@
     }
 #endif
 
-    return (name_prime->serialize (c->serializer, it,
-                                   std::addressof (this + stringOffset)
+    return name_prime->serialize (c->serializer, it,
+                                  std::addressof (this + stringOffset)
 #ifdef HB_EXPERIMENTAL_API
-                                   , insert_name_records
-                                   , name_table_overrides
+                                  , insert_name_records
+                                  , name_table_overrides
 #endif
-                                   ));
+                                  );
   }
 
   bool sanitize_records (hb_sanitize_context_t *c) const
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/UPDATING.txt openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/UPDATING.txt
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/UPDATING.txt	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/UPDATING.txt	2024-01-16 16:19:00.000000000 +0000
@@ -106,7 +106,7 @@
   Look for manual related layout jtreg tests (test/jdk/java/awt/font/TextLayout)
   and run on Windows,Linux and Mac.
   Use Font2DTest set to TextLayout and check the above languages. Probably
-  not going to see layout problems a code point at a time but it needs to
+  not going to see layout problems in code at this point of time but it needs to
   be checked.
 
   Different unicode combinations can be checked using Font2DTest.
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -72,7 +72,7 @@
     class_def_link->width = SmallTypes::size;
     class_def_link->objidx = class_def_prime_id;
     class_def_link->position = link_position;
-    class_def_prime_vertex.parents.push (parent_id);
+    class_def_prime_vertex.add_parent (parent_id);
 
     return true;
   }
@@ -94,7 +94,13 @@
     }
 
     hb_bytes_t class_def_copy = serializer.copy_bytes ();
-    c.add_buffer ((char *) class_def_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
+    if (!class_def_copy.arrayZ) return false;
+    // Give ownership to the context, it will cleanup the buffer.
+    if (!c.add_buffer ((char *) class_def_copy.arrayZ))
+    {
+      hb_free ((char *) class_def_copy.arrayZ);
+      return false;
+    }
 
     auto& obj = c.graph.vertices_[dest_obj].obj;
     obj.head = (char *) class_def_copy.arrayZ;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -96,7 +96,7 @@
     coverage_link->width = SmallTypes::size;
     coverage_link->objidx = coverage_prime_id;
     coverage_link->position = link_position;
-    coverage_prime_vertex.parents.push (parent_id);
+    coverage_prime_vertex.add_parent (parent_id);
 
     return (Coverage*) coverage_prime_vertex.obj.head;
   }
@@ -118,7 +118,13 @@
     }
 
     hb_bytes_t coverage_copy = serializer.copy_bytes ();
-    c.add_buffer ((char *) coverage_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
+    if (!coverage_copy.arrayZ) return false;
+    // Give ownership to the context, it will cleanup the buffer.
+    if (!c.add_buffer ((char *) coverage_copy.arrayZ))
+    {
+      hb_free ((char *) coverage_copy.arrayZ);
+      return false;
+    }
 
     auto& obj = c.graph.vertices_[dest_obj].obj;
     obj.head = (char *) coverage_copy.arrayZ;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/graph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/graph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/graph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/graph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -43,12 +43,28 @@
   {
     hb_serialize_context_t::object_t obj;
     int64_t distance = 0 ;
-    int64_t space = 0 ;
-    hb_vector_t parents;
+    unsigned space = 0 ;
     unsigned start = 0;
     unsigned end = 0;
     unsigned priority = 0;
+    private:
+    unsigned incoming_edges_ = 0;
+    unsigned single_parent = (unsigned) -1;
+    hb_hashmap_t parents;
+    public:
+
+    auto parents_iter () const HB_AUTO_RETURN
+    (
+      hb_concat (
+        hb_iter (&single_parent, single_parent != (unsigned) -1),
+        parents.keys_ref ()
+      )
+    )
 
+    bool in_error () const
+    {
+      return parents.in_error ();
+    }
 
     bool link_positions_valid (unsigned num_objects, bool removed_nil)
     {
@@ -143,7 +159,9 @@
       hb_swap (a.obj, b.obj);
       hb_swap (a.distance, b.distance);
       hb_swap (a.space, b.space);
+      hb_swap (a.single_parent, b.single_parent);
       hb_swap (a.parents, b.parents);
+      hb_swap (a.incoming_edges_, b.incoming_edges_);
       hb_swap (a.start, b.start);
       hb_swap (a.end, b.end);
       hb_swap (a.priority, b.priority);
@@ -154,6 +172,7 @@
     {
       hb_hashmap_t result;
 
+      result.alloc (obj.real_links.length);
       for (const auto& l : obj.real_links) {
         result.set (l.position, l.objidx);
       }
@@ -163,27 +182,83 @@
 
     bool is_shared () const
     {
-      return parents.length > 1;
+      return parents.get_population () > 1;
     }
 
     unsigned incoming_edges () const
     {
-      return parents.length;
+      if (HB_DEBUG_SUBSET_REPACK)
+       {
+        assert (incoming_edges_ == (single_parent != (unsigned) -1) +
+                (parents.values_ref () | hb_reduce (hb_add, 0)));
+       }
+      return incoming_edges_;
+    }
+
+    void reset_parents ()
+    {
+      incoming_edges_ = 0;
+      single_parent = (unsigned) -1;
+      parents.reset ();
+    }
+
+    void add_parent (unsigned parent_index)
+    {
+      assert (parent_index != (unsigned) -1);
+      if (incoming_edges_ == 0)
+      {
+        single_parent = parent_index;
+        incoming_edges_ = 1;
+        return;
+      }
+      else if (single_parent != (unsigned) -1)
+      {
+        assert (incoming_edges_ == 1);
+        if (!parents.set (single_parent, 1))
+          return;
+        single_parent = (unsigned) -1;
+      }
+
+      unsigned *v;
+      if (parents.has (parent_index, &v))
+      {
+        (*v)++;
+        incoming_edges_++;
+      }
+      else if (parents.set (parent_index, 1))
+        incoming_edges_++;
     }
 
     void remove_parent (unsigned parent_index)
     {
-      for (unsigned i = 0; i < parents.length; i++)
+      if (parent_index == single_parent)
+      {
+        single_parent = (unsigned) -1;
+        incoming_edges_--;
+        return;
+      }
+
+      unsigned *v;
+      if (parents.has (parent_index, &v))
       {
-        if (parents[i] != parent_index) continue;
-        parents.remove_unordered (i);
-        break;
+        incoming_edges_--;
+        if (*v > 1)
+          (*v)--;
+        else
+          parents.del (parent_index);
+
+        if (incoming_edges_ == 1)
+        {
+          single_parent = *parents.keys ();
+          parents.reset ();
+        }
       }
     }
 
     void remove_real_link (unsigned child_index, const void* offset)
     {
-      for (unsigned i = 0; i < obj.real_links.length; i++)
+      unsigned count = obj.real_links.length;
+      for (unsigned i = 0; i < count; i++)
       {
         auto& link = obj.real_links.arrayZ[i];
         if (link.objidx != child_index)
@@ -197,18 +272,53 @@
       }
     }
 
-    void remap_parents (const hb_vector_t& id_map)
+    bool remap_parents (const hb_vector_t& id_map)
     {
-      for (unsigned i = 0; i < parents.length; i++)
-        parents[i] = id_map[parents[i]];
+      if (single_parent != (unsigned) -1)
+      {
+        assert (single_parent < id_map.length);
+        single_parent = id_map[single_parent];
+        return true;
+      }
+
+      hb_hashmap_t new_parents;
+      new_parents.alloc (parents.get_population ());
+      for (auto _ : parents)
+      {
+        assert (_.first < id_map.length);
+        assert (!new_parents.has (id_map[_.first]));
+        new_parents.set (id_map[_.first], _.second);
+      }
+
+      if (parents.in_error() || new_parents.in_error ())
+        return false;
+
+      parents = std::move (new_parents);
+      return true;
     }
 
     void remap_parent (unsigned old_index, unsigned new_index)
     {
-      for (unsigned i = 0; i < parents.length; i++)
+      if (single_parent != (unsigned) -1)
       {
-        if (parents[i] == old_index)
-          parents[i] = new_index;
+        if (single_parent == old_index)
+          single_parent = new_index;
+        return;
+      }
+
+      const unsigned *pv;
+      if (parents.has (old_index, &pv))
+      {
+        unsigned v = *pv;
+        if (!parents.set (new_index, v))
+          incoming_edges_ -= v;
+        parents.del (old_index);
+
+        if (incoming_edges_ == 1)
+        {
+          single_parent = *parents.keys ();
+          parents.reset ();
+        }
       }
     }
 
@@ -328,11 +438,12 @@
     bool removed_nil = false;
     vertices_.alloc (objects.length);
     vertices_scratch_.alloc (objects.length);
-    for (unsigned i = 0; i < objects.length; i++)
+    unsigned count = objects.length;
+    for (unsigned i = 0; i < count; i++)
     {
       // If this graph came from a serialization buffer object 0 is the
       // nil object. We don't need it for our purposes here so drop it.
-      if (i == 0 && !objects[i])
+      if (i == 0 && !objects.arrayZ[i])
       {
         removed_nil = true;
         continue;
@@ -340,9 +451,9 @@
 
       vertex_t* v = vertices_.push ();
       if (check_success (!vertices_.in_error ()))
-        v->obj = *objects[i];
+        v->obj = *objects.arrayZ[i];
 
-      check_success (v->link_positions_valid (objects.length, removed_nil));
+      check_success (v->link_positions_valid (count, removed_nil));
 
       if (!removed_nil) continue;
       // Fix indices to account for removed nil object.
@@ -354,7 +465,6 @@
 
   ~graph_t ()
   {
-    vertices_.fini ();
     for (char* b : buffers)
       hb_free (b);
   }
@@ -364,6 +474,18 @@
     return root ().equals (other.root (), *this, other, 0);
   }
 
+  void print () const {
+    for (int i = vertices_.length - 1; i >= 0; i--)
+    {
+      const auto& v = vertices_[i];
+      printf("%d: %u [", i, (unsigned int)v.table_size());
+      for (const auto &l : v.obj.real_links) {
+        printf("%u, ", l.objidx);
+      }
+      printf("]\n");
+    }
+  }
+
   // Sorts links of all objects in a consistent manner and zeroes all offsets.
   void normalize ()
   {
@@ -396,9 +518,10 @@
     return vertices_[i].obj;
   }
 
-  void add_buffer (char* buffer)
+  bool add_buffer (char* buffer)
   {
     buffers.push (buffer);
+    return !buffers.in_error ();
   }
 
   /*
@@ -414,7 +537,7 @@
     link->width = 2;
     link->objidx = child_id;
     link->position = (char*) offset - (char*) v.obj.head;
-    vertices_[child_id].parents.push (parent_id);
+    vertices_[child_id].add_parent (parent_id);
   }
 
   /*
@@ -443,7 +566,7 @@
 
     update_distances ();
 
-    hb_priority_queue_t queue;
+    hb_priority_queue_t queue;
     hb_vector_t &sorted_graph = vertices_scratch_;
     if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
     hb_vector_t id_map;
@@ -460,7 +583,7 @@
     {
       unsigned next_id = queue.pop_minimum().second;
 
-      hb_swap (sorted_graph[new_id], vertices_[next_id]);
+      sorted_graph[new_id] = std::move (vertices_[next_id]);
       const vertex_t& next = sorted_graph[new_id];
 
       if (unlikely (!check_success(new_id >= 0))) {
@@ -488,8 +611,8 @@
     check_success (!queue.in_error ());
     check_success (!sorted_graph.in_error ());
 
-    remap_all_obj_indices (id_map, &sorted_graph);
-    hb_swap (vertices_, sorted_graph);
+    check_success (remap_all_obj_indices (id_map, &sorted_graph));
+    vertices_ = std::move (sorted_graph);
 
     if (!check_success (new_id == -1))
       print_orphaned_nodes ();
@@ -579,8 +702,8 @@
     const auto& node = object (node_idx);
     if (offset < node.head || offset >= node.tail) return -1;
 
-    unsigned length = node.real_links.length;
-    for (unsigned i = 0; i < length; i++)
+    unsigned count = node.real_links.length;
+    for (unsigned i = 0; i < count; i++)
     {
       // Use direct access for increased performance, this is a hot method.
       const auto& link = node.real_links.arrayZ[i];
@@ -600,7 +723,7 @@
   {
     unsigned child_idx = index_for_offset (node_idx, offset);
     auto& child = vertices_[child_idx];
-    for (unsigned p : child.parents)
+    for (unsigned p : child.parents_iter ())
     {
       if (p != node_idx) {
         return duplicate (node_idx, child_idx);
@@ -683,12 +806,15 @@
       subgraph.set (root_idx, wide_parents (root_idx, parents));
       find_subgraph (root_idx, subgraph);
     }
+    if (subgraph.in_error ())
+      return false;
 
     unsigned original_root_idx = root_idx ();
     hb_map_t index_map;
     bool made_changes = false;
     for (auto entry : subgraph.iter ())
     {
+      assert (entry.first < vertices_.length);
       const auto& node = vertices_[entry.first];
       unsigned subgraph_incoming_edges = entry.second;
 
@@ -727,8 +853,7 @@
     remap_obj_indices (index_map, parents.iter (), true);
 
     // Update roots set with new indices as needed.
-    uint32_t next = HB_SET_VALUE_INVALID;
-    while (roots.next (&next))
+    for (auto next : roots)
     {
       const uint32_t *v;
       if (index_map.has (next, &v))
@@ -745,10 +870,10 @@
   {
     for (const auto& link : vertices_[node_idx].obj.all_links ())
     {
-      const uint32_t *v;
+      hb_codepoint_t *v;
       if (subgraph.has (link.objidx, &v))
       {
-        subgraph.set (link.objidx, *v + 1);
+        (*v)++;
         continue;
       }
       subgraph.set (link.objidx, 1);
@@ -820,7 +945,7 @@
     new_link->position = (const char*) new_offset - (const char*) new_v.obj.head;
 
     auto& child = vertices_[child_id];
-    child.parents.push (new_parent_idx);
+    child.add_parent (new_parent_idx);
 
     old_v.remove_real_link (child_id, old_offset);
     child.remove_parent (old_parent_idx);
@@ -864,18 +989,18 @@
     clone->obj.tail = child.obj.tail;
     clone->distance = child.distance;
     clone->space = child.space;
-    clone->parents.reset ();
+    clone->reset_parents ();
 
     unsigned clone_idx = vertices_.length - 2;
     for (const auto& l : child.obj.real_links)
     {
       clone->obj.real_links.push (l);
-      vertices_[l.objidx].parents.push (clone_idx);
+      vertices_[l.objidx].add_parent (clone_idx);
     }
     for (const auto& l : child.obj.virtual_links)
     {
       clone->obj.virtual_links.push (l);
-      vertices_[l.objidx].parents.push (clone_idx);
+      vertices_[l.objidx].add_parent (clone_idx);
     }
 
     check_success (!clone->obj.real_links.in_error ());
@@ -1004,13 +1129,13 @@
   {
     update_parents();
 
-    if (root().parents)
+    if (root().incoming_edges ())
       // Root cannot have parents.
       return false;
 
     for (unsigned i = 0; i < root_idx (); i++)
     {
-      if (!vertices_[i].parents)
+      if (!vertices_[i].incoming_edges ())
         return false;
     }
     return true;
@@ -1074,14 +1199,14 @@
     parents_invalid = true;
     update_parents();
 
-    if (root().parents) {
+    if (root().incoming_edges ()) {
       DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges.");
     }
 
     for (unsigned i = 0; i < root_idx (); i++)
     {
       const auto& v = vertices_[i];
-      if (!v.parents)
+      if (!v.incoming_edges ())
         DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i);
     }
   }
@@ -1113,6 +1238,8 @@
 
   unsigned space_for (unsigned index, unsigned* root = nullptr) const
   {
+  loop:
+    assert (index < vertices_.length);
     const auto& node = vertices_[index];
     if (node.space)
     {
@@ -1121,22 +1248,24 @@
       return node.space;
     }
 
-    if (!node.parents)
+    if (!node.incoming_edges ())
     {
       if (root)
         *root = index;
       return 0;
     }
 
-    return space_for (node.parents[0], root);
+    index = *node.parents_iter ();
+    goto loop;
   }
 
   void err_other_error () { this->successful = false; }
 
   size_t total_size_in_bytes () const {
     size_t total_size = 0;
-    for (unsigned i = 0; i < vertices_.length; i++) {
-      size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
+    unsigned count = vertices_.length;
+    for (unsigned i = 0; i < count; i++) {
+      size_t size = vertices_.arrayZ[i].obj.tail - vertices_.arrayZ[i].obj.head;
       total_size += size;
     }
     return total_size;
@@ -1151,12 +1280,8 @@
   unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
   {
     unsigned count = 0;
-    hb_set_t visited;
-    for (unsigned p : vertices_[node_idx].parents)
+    for (unsigned p : vertices_[node_idx].parents_iter ())
     {
-      if (visited.has (p)) continue;
-      visited.add (p);
-
       // Only real links can be wide
       for (const auto& l : vertices_[p].obj.real_links)
       {
@@ -1183,21 +1308,21 @@
   {
     if (!parents_invalid) return;
 
-    for (unsigned i = 0; i < vertices_.length; i++)
-      vertices_[i].parents.reset ();
+    unsigned count = vertices_.length;
+
+    for (unsigned i = 0; i < count; i++)
+      vertices_.arrayZ[i].reset_parents ();
 
-    for (unsigned p = 0; p < vertices_.length; p++)
+    for (unsigned p = 0; p < count; p++)
     {
-      for (auto& l : vertices_[p].obj.all_links ())
-      {
-        vertices_[l.objidx].parents.push (p);
-      }
+      for (auto& l : vertices_.arrayZ[p].obj.all_links ())
+        vertices_[l.objidx].add_parent (p);
     }
 
-    for (unsigned i = 0; i < vertices_.length; i++)
+    for (unsigned i = 0; i < count; i++)
       // parents arrays must be accurate or downstream operations like cycle detection
       // and sorting won't work correctly.
-      check_success (!vertices_[i].parents.in_error ());
+      check_success (!vertices_.arrayZ[i].in_error ());
 
     parents_invalid = false;
   }
@@ -1239,15 +1364,12 @@
     // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
     // for practical performance this is faster then using a more advanced queue
     // (such as a fibonacci queue) with a fast decrease priority.
-    for (unsigned i = 0; i < vertices_.length; i++)
-    {
-      if (i == vertices_.length - 1)
-        vertices_[i].distance = 0;
-      else
-        vertices_[i].distance = hb_int_max (int64_t);
-    }
+    unsigned count = vertices_.length;
+    for (unsigned i = 0; i < count; i++)
+      vertices_.arrayZ[i].distance = hb_int_max (int64_t);
+    vertices_.tail ().distance = 0;
 
-    hb_priority_queue_t queue;
+    hb_priority_queue_t queue;
     queue.insert (0, vertices_.length - 1);
 
     hb_vector_t visited;
@@ -1265,15 +1387,15 @@
       {
         if (visited[link.objidx]) continue;
 
-        const auto& child = vertices_[link.objidx].obj;
+        const auto& child = vertices_.arrayZ[link.objidx].obj;
         unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
         int64_t child_weight = (child.tail - child.head) +
-                               ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
+                               ((int64_t) 1 << (link_width * 8)) * (vertices_.arrayZ[link.objidx].space + 1);
         int64_t child_distance = next_distance + child_weight;
 
-        if (child_distance < vertices_[link.objidx].distance)
+        if (child_distance < vertices_.arrayZ[link.objidx].distance)
         {
-          vertices_[link.objidx].distance = child_distance;
+          vertices_.arrayZ[link.objidx].distance = child_distance;
           queue.insert (child_distance, link.objidx);
         }
       }
@@ -1301,7 +1423,7 @@
     unsigned old_idx = link.objidx;
     link.objidx = new_idx;
     vertices_[old_idx].remove_parent (parent_idx);
-    vertices_[new_idx].parents.push (parent_idx);
+    vertices_[new_idx].add_parent (parent_idx);
   }
 
   /*
@@ -1329,17 +1451,20 @@
   /*
    * Updates all objidx's in all links using the provided mapping.
    */
-  void remap_all_obj_indices (const hb_vector_t& id_map,
+  bool remap_all_obj_indices (const hb_vector_t& id_map,
                               hb_vector_t* sorted_graph) const
   {
-    for (unsigned i = 0; i < sorted_graph->length; i++)
+    unsigned count = sorted_graph->length;
+    for (unsigned i = 0; i < count; i++)
     {
-      (*sorted_graph)[i].remap_parents (id_map);
-      for (auto& link : (*sorted_graph)[i].obj.all_links_writer ())
+      if (!(*sorted_graph)[i].remap_parents (id_map))
+        return false;
+      for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ())
       {
         link.objidx = id_map[link.objidx];
       }
     }
+    return true;
   }
 
   /*
@@ -1370,7 +1495,7 @@
     for (const auto& l : v.obj.all_links ())
       find_connected_nodes (l.objidx, targets, visited, connected);
 
-    for (unsigned p : v.parents)
+    for (unsigned p : v.parents_iter ())
       find_connected_nodes (p, targets, visited, connected);
   }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc	2024-01-16 16:19:00.000000000 +0000
@@ -52,7 +52,11 @@
   if (!buffer)
     return -1;
 
-  add_buffer (buffer);
+  if (!add_buffer (buffer)) {
+    // Allocation did not get stored for freeing later.
+    hb_free (buffer);
+    return -1;
+  }
 
   return graph.new_node (buffer, buffer + size);
 }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh	2024-01-16 16:19:00.000000000 +0000
@@ -40,16 +40,16 @@
   graph_t& graph;
   unsigned lookup_list_index;
   hb_hashmap_t lookups;
-
+  hb_hashmap_t subtable_to_extension;
 
   HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_,
                                         graph_t& graph_);
 
   HB_INTERNAL unsigned create_node (unsigned size);
 
-  void add_buffer (char* buffer)
+  bool add_buffer (char* buffer)
   {
-    graph.add_buffer (buffer);
+    return graph.add_buffer (buffer);
   }
 
  private:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -166,7 +166,7 @@
     }
 
     if (all_new_subtables) {
-      add_sub_tables (c, this_index, type, all_new_subtables);
+      return add_sub_tables (c, this_index, type, all_new_subtables);
     }
 
     return true;
@@ -184,7 +184,7 @@
     return sub_table->split_subtables (c, parent_idx, objidx);
   }
 
-  void add_sub_tables (gsubgpos_graph_context_t& c,
+  bool add_sub_tables (gsubgpos_graph_context_t& c,
                        unsigned this_index,
                        unsigned type,
                        hb_vector_t>>& subtable_ids)
@@ -200,7 +200,12 @@
     size_t new_size = v.table_size ()
                       + new_subtable_count * OT::Offset16::static_size;
     char* buffer = (char*) hb_calloc (1, new_size);
-    c.add_buffer (buffer);
+    if (!buffer) return false;
+    if (!c.add_buffer (buffer))
+    {
+      hb_free (buffer);
+     return false;
+    }
     hb_memcpy (buffer, v.obj.head, v.table_size());
 
     v.obj.head = buffer;
@@ -220,7 +225,7 @@
         if (is_ext)
         {
           unsigned ext_id = create_extension_subtable (c, subtable_id, type);
-          c.graph.vertices_[subtable_id].parents.push (ext_id);
+          c.graph.vertices_[subtable_id].add_parent (ext_id);
           subtable_id = ext_id;
         }
 
@@ -229,7 +234,7 @@
         link->objidx = subtable_id;
         link->position = (char*) &new_lookup->subTable[offset_index++] -
                          (char*) new_lookup;
-        c.graph.vertices_[subtable_id].parents.push (this_index);
+        c.graph.vertices_[subtable_id].add_parent (this_index);
       }
     }
 
@@ -239,6 +244,7 @@
     // The head location of the lookup has changed, invalidating the lookups map entry
     // in the context. Update the map.
     c.lookups.set (this_index, new_lookup);
+    return true;
   }
 
   void fix_existing_subtable_links (gsubgpos_graph_context_t& c,
@@ -293,24 +299,35 @@
                                 unsigned subtable_index)
   {
     unsigned type = lookupType;
+    unsigned ext_index = -1;
+    unsigned* existing_ext_index = nullptr;
+    if (c.subtable_to_extension.has(subtable_index, &existing_ext_index)) {
+      ext_index = *existing_ext_index;
+    } else {
+      ext_index = create_extension_subtable(c, subtable_index, type);
+      c.subtable_to_extension.set(subtable_index, ext_index);
+    }
 
-    unsigned ext_index = create_extension_subtable(c, subtable_index, type);
     if (ext_index == (unsigned) -1)
       return false;
 
+    auto& subtable_vertex = c.graph.vertices_[subtable_index];
     auto& lookup_vertex = c.graph.vertices_[lookup_index];
     for (auto& l : lookup_vertex.obj.real_links.writer ())
     {
-      if (l.objidx == subtable_index)
+      if (l.objidx == subtable_index) {
         // Change lookup to point at the extension.
         l.objidx = ext_index;
+        if (existing_ext_index)
+          subtable_vertex.remove_parent(lookup_index);
+      }
     }
 
     // Make extension point at the subtable.
     auto& ext_vertex = c.graph.vertices_[ext_index];
-    auto& subtable_vertex = c.graph.vertices_[subtable_index];
-    ext_vertex.parents.push (lookup_index);
-    subtable_vertex.remap_parent (lookup_index, ext_index);
+    ext_vertex.add_parent (lookup_index);
+    if (!existing_ext_index)
+      subtable_vertex.remap_parent (lookup_index, ext_index);
 
     return true;
   }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -217,7 +217,7 @@
 
     const unsigned base_coverage_id = c.graph.index_for_offset (this_index, &baseCoverage);
     const unsigned base_size =
-        OT::Layout::GPOS_impl::PairPosFormat1_3::min_size +
+        OT::Layout::GPOS_impl::MarkBasePosFormat1_2::min_size +
         MarkArray::min_size +
         AnchorMatrix::min_size +
         c.graph.vertices_[base_coverage_id].table_size ();
@@ -318,8 +318,11 @@
   {
     hb_vector_t class_to_info;
 
-    unsigned class_count= classCount;
-    class_to_info.resize (class_count);
+    unsigned class_count = classCount;
+    if (!class_count) return class_to_info;
+
+    if (!class_to_info.resize (class_count))
+      return hb_vector_t();
 
     auto mark_array = c.graph.as_table (this_index, &markArray);
     if (!mark_array) return hb_vector_t ();
@@ -327,6 +330,7 @@
     for (unsigned mark = 0; mark < mark_count; mark++)
     {
       unsigned klass = (*mark_array.table)[mark].get_class ();
+      if (klass >= class_count) continue;
       class_to_info[klass].marks.add (mark);
     }
 
@@ -335,6 +339,7 @@
       unsigned mark = (link.position - 2) /
                      OT::Layout::GPOS_impl::MarkRecord::static_size;
       unsigned klass = (*mark_array.table)[mark].get_class ();
+      if (klass >= class_count) continue;
       class_to_info[klass].child_indices.push (link.objidx);
     }
 
@@ -479,7 +484,7 @@
       return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
 #ifndef HB_NO_BEYOND_64K
     case 2: HB_FALLTHROUGH;
-      // Don't split 24bit PairPos's.
+      // Don't split 24bit MarkBasePos's.
 #endif
     default:
       return hb_vector_t ();
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh	2024-01-16 16:19:00.000000000 +0000
@@ -215,7 +215,7 @@
     auto gid_and_class =
         + coverage->iter ()
         | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
-          return hb_pair_t (gid, class_def_1->get_class (gid));
+          return hb_codepoint_pair_t (gid, class_def_1->get_class (gid));
         })
         ;
     class_def_size_estimator_t estimator (gid_and_class);
@@ -386,14 +386,14 @@
     auto klass_map =
     + coverage_table->iter ()
     | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
-      return hb_pair_t (gid, class_def_1_table->get_class (gid));
+      return hb_codepoint_pair_t (gid, class_def_1_table->get_class (gid));
     })
     | hb_filter ([&] (hb_codepoint_t klass) {
       return klass >= start && klass < end;
     }, hb_second)
-    | hb_map_retains_sorting ([&] (hb_pair_t gid_and_class) {
+    | hb_map_retains_sorting ([&] (hb_codepoint_pair_t gid_and_class) {
       // Classes must be from 0...N so subtract start
-      return hb_pair_t (gid_and_class.first, gid_and_class.second - start);
+      return hb_codepoint_pair_t (gid_and_class.first, gid_and_class.second - start);
     })
     ;
 
@@ -419,7 +419,7 @@
     class_def_link->width = SmallTypes::size;
     class_def_link->objidx = class_def_2_id;
     class_def_link->position = 10;
-    graph.vertices_[class_def_2_id].parents.push (pair_pos_prime_id);
+    graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id);
     graph.duplicate (pair_pos_prime_id, class_def_2_id);
 
     return pair_pos_prime_id;
@@ -519,7 +519,7 @@
     auto klass_map =
     + coverage.table->iter ()
     | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
-      return hb_pair_t (gid, class_def_1.table->get_class (gid));
+      return hb_codepoint_pair_t (gid, class_def_1.table->get_class (gid));
     })
     | hb_filter ([&] (hb_codepoint_t klass) {
       return klass < count;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh	2024-01-16 16:19:00.000000000 +0000
@@ -116,10 +116,10 @@
   for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--)
   {
     // Don't need to check virtual links for overflow
-    for (const auto& link : vertices[parent_idx].obj.real_links)
+    for (const auto& link : vertices.arrayZ[parent_idx].obj.real_links)
     {
       int64_t offset = compute_offset (graph, parent_idx, link);
-      if (is_valid_offset (offset, link))
+      if (likely (is_valid_offset (offset, link)))
         continue;
 
       if (!overflows) return true;
@@ -226,6 +226,9 @@
 {
   hb_vector_t buffer;
   size_t size = graph.total_size_in_bytes ();
+
+  if (!size) return hb_blob_get_empty ();
+
   if (!buffer.alloc (size)) {
     DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer.");
     return nullptr;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -851,43 +851,41 @@
        *
        *   https://github.com/harfbuzz/harfbuzz/issues/2860
        */
-      const EntryT *wouldbe_entry;
-      bool safe_to_break =
-        /* 1. */
-        !c->is_actionable (this, entry)
-      &&
-        /* 2. */
-        (
-          /* 2a. */
-          state == StateTableT::STATE_START_OF_TEXT
-        ||
-          /* 2b. */
-          (
-            (entry.flags & context_t::DontAdvance) &&
-            next_state == StateTableT::STATE_START_OF_TEXT
-          )
-        ||
+
+      const auto is_safe_to_break_extra = [&]()
+      {
           /* 2c. */
-          (
-            wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
-          ,
-            /* 2c'. */
-            !c->is_actionable (this, *wouldbe_entry)
-          &&
-            /* 2c". */
-            (
-              next_state == machine.new_state (wouldbe_entry->newState)
-            &&
-              (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
-            )
-          )
-        )
-      &&
-        /* 3. */
-        !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
-      ;
+          const auto wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass);
+
+          /* 2c'. */
+          if (c->is_actionable (this, wouldbe_entry))
+              return false;
+
+          /* 2c". */
+          return next_state == machine.new_state(wouldbe_entry.newState)
+              && (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance);
+      };
+
+      const auto is_safe_to_break = [&]()
+      {
+          /* 1. */
+          if (c->is_actionable (this, entry))
+              return false;
+
+          /* 2. */
+          // This one is meh, I know...
+          const auto ok =
+                 state == StateTableT::STATE_START_OF_TEXT
+              || ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT)
+              || is_safe_to_break_extra();
+          if (!ok)
+              return false;
+
+          /* 3. */
+          return !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT));
+      };
 
-      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
+      if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len)
         buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
 
       c->transition (this, entry);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -111,13 +111,13 @@
         break;
       }
     }
-    if (!trackTableEntry) return 0.;
+    if (!trackTableEntry) return 0;
 
     /*
      * Choose size.
      */
     unsigned int sizes = nSizes;
-    if (!sizes) return 0.;
+    if (!sizes) return 0;
     if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
 
     hb_array_t size_table ((base+sizeTable).arrayZ, sizes);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc	2024-01-16 16:19:00.000000000 +0000
@@ -55,7 +55,13 @@
                                                        buffer (buffer_),
                                                        sanitizer (),
                                                        ankr_table (&Null (AAT::ankr)),
-                                                       gdef_table (face->table.GDEF->table),
+                                                       gdef_table (
+#ifndef HB_NO_OT_LAYOUT
+                                                         face->table.GDEF->table
+#else
+                                                         &Null (GDEF)
+#endif
+                                                       ),
                                                        lookup_index (0)
 {
   sanitizer.init (blob);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-algs.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-algs.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-algs.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-algs.hh	2024-01-16 16:19:00.000000000 +0000
@@ -87,6 +87,19 @@
 static inline constexpr uint32_t hb_uint32_swap (uint32_t v)
 { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
 
+#ifndef HB_FAST_INT_ACCESS
+#if defined(__OPTIMIZE__) && \
+    defined(__BYTE_ORDER) && \
+    (__BYTE_ORDER == __BIG_ENDIAN || \
+     (__BYTE_ORDER == __LITTLE_ENDIAN && \
+      hb_has_builtin(__builtin_bswap16) && \
+      hb_has_builtin(__builtin_bswap32)))
+#define HB_FAST_INT_ACCESS 1
+#else
+#define HB_FAST_INT_ACCESS 0
+#endif
+#endif
+
 template 
 struct BEInt;
 template 
@@ -101,21 +114,25 @@
 template 
 struct BEInt
 {
+  struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
+
   public:
   BEInt () = default;
-  constexpr BEInt (Type V) : v {uint8_t ((V >>  8) & 0xFF),
-                                uint8_t ((V      ) & 0xFF)} {}
 
-  struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
-  constexpr operator Type () const
-  {
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    defined(__BYTE_ORDER) && \
-    (__BYTE_ORDER == __BIG_ENDIAN || \
-     (__BYTE_ORDER == __LITTLE_ENDIAN && \
-      hb_has_builtin(__builtin_bswap16)))
-    /* Spoon-feed the compiler a big-endian integer with alignment 1.
-     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
+  BEInt (Type V)
+#if HB_FAST_INT_ACCESS
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+  { ((packed_uint16_t *) v)->v = __builtin_bswap16 (V); }
+#else /* __BYTE_ORDER == __BIG_ENDIAN */
+  { ((packed_uint16_t *) v)->v = V; }
+#endif
+#else
+    : v {uint8_t ((V >>  8) & 0xFF),
+         uint8_t ((V      ) & 0xFF)} {}
+#endif
+
+  constexpr operator Type () const {
+#if HB_FAST_INT_ACCESS
 #if __BYTE_ORDER == __LITTLE_ENDIAN
     return __builtin_bswap16 (((packed_uint16_t *) v)->v);
 #else /* __BYTE_ORDER == __BIG_ENDIAN */
@@ -146,22 +163,27 @@
 template 
 struct BEInt
 {
+  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+
   public:
   BEInt () = default;
-  constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF),
-                                uint8_t ((V >> 16) & 0xFF),
-                                uint8_t ((V >>  8) & 0xFF),
-                                uint8_t ((V      ) & 0xFF)} {}
 
-  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+  BEInt (Type V)
+#if HB_FAST_INT_ACCESS
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+  { ((packed_uint32_t *) v)->v = __builtin_bswap32 (V); }
+#else /* __BYTE_ORDER == __BIG_ENDIAN */
+  { ((packed_uint32_t *) v)->v = V; }
+#endif
+#else
+    : v {uint8_t ((V >> 24) & 0xFF),
+         uint8_t ((V >> 16) & 0xFF),
+         uint8_t ((V >>  8) & 0xFF),
+         uint8_t ((V      ) & 0xFF)} {}
+#endif
+
   constexpr operator Type () const {
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    defined(__BYTE_ORDER) && \
-    (__BYTE_ORDER == __BIG_ENDIAN || \
-     (__BYTE_ORDER == __LITTLE_ENDIAN && \
-      hb_has_builtin(__builtin_bswap32)))
-    /* Spoon-feed the compiler a big-endian integer with alignment 1.
-     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
+#if HB_FAST_INT_ACCESS
 #if __BYTE_ORDER == __LITTLE_ENDIAN
     return __builtin_bswap32 (((packed_uint32_t *) v)->v);
 #else /* __BYTE_ORDER == __BIG_ENDIAN */
@@ -231,12 +253,123 @@
 }
 HB_FUNCOBJ (hb_bool);
 
+
+/* The MIT License
+
+   Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
+
+   Permission is hereby granted, free of charge, to any person
+   obtaining a copy of this software and associated documentation
+   files (the "Software"), to deal in the Software without
+   restriction, including without limitation the rights to use, copy,
+   modify, merge, publish, distribute, sublicense, and/or sell copies
+   of the Software, and to permit persons to whom the Software is
+   furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be
+   included in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+   SOFTWARE.
+*/
+
+
+// Compression function for Merkle-Damgard construction.
+// This function is generated using the framework provided.
+#define mix(h) (                                        \
+                        (void) ((h) ^= (h) >> 23),              \
+                        (void) ((h) *= 0x2127599bf4325c37ULL),  \
+                        (h) ^= (h) >> 47)
+
+static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
+{
+        struct __attribute__((packed)) packed_uint64_t { uint64_t v; };
+        const uint64_t    m = 0x880355f21e6d1965ULL;
+        const packed_uint64_t *pos = (const packed_uint64_t *)buf;
+        const packed_uint64_t *end = pos + (len / 8);
+        const unsigned char *pos2;
+        uint64_t h = seed ^ (len * m);
+        uint64_t v;
+
+#ifndef HB_OPTIMIZE_SIZE
+        if (((uintptr_t) pos & 7) == 0)
+        {
+          while (pos != end)
+          {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+            v  = * (const uint64_t *) (pos++);
+#pragma GCC diagnostic pop
+            h ^= mix(v);
+            h *= m;
+          }
+        }
+        else
+#endif
+        {
+          while (pos != end)
+          {
+            v  = pos++->v;
+            h ^= mix(v);
+            h *= m;
+          }
+        }
+
+        pos2 = (const unsigned char*)pos;
+        v = 0;
+
+        switch (len & 7) {
+        case 7: v ^= (uint64_t)pos2[6] << 48; HB_FALLTHROUGH;
+        case 6: v ^= (uint64_t)pos2[5] << 40; HB_FALLTHROUGH;
+        case 5: v ^= (uint64_t)pos2[4] << 32; HB_FALLTHROUGH;
+        case 4: v ^= (uint64_t)pos2[3] << 24; HB_FALLTHROUGH;
+        case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH;
+        case 2: v ^= (uint64_t)pos2[1] <<  8; HB_FALLTHROUGH;
+        case 1: v ^= (uint64_t)pos2[0];
+                h ^= mix(v);
+                h *= m;
+        }
+
+        return mix(h);
+}
+
+static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed)
+{
+        // the following trick converts the 64-bit hashcode to Fermat
+        // residue, which shall retain information from both the higher
+        // and lower parts of hashcode.
+        uint64_t h = fasthash64(buf, len, seed);
+        return h - (h >> 32);
+}
+
 struct
 {
   private:
 
   template  constexpr auto
-  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+  impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+
+  // Horrible: std:hash() of integers seems to be identity in gcc / clang?!
+  // https://github.com/harfbuzz/harfbuzz/pull/4228
+  //
+  // For performance characteristics see:
+  // https://github.com/harfbuzz/harfbuzz/pull/4228#issuecomment-1565079537
+  template ::value && sizeof (T) <= sizeof (uint32_t))> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) v * 2654435761u /* Knuh's multiplicative hash */)
+  template ::value && sizeof (T) > sizeof (uint32_t))> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */)
+
+  template ::value)> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, fasthash32 (std::addressof (v), sizeof (T), 0xf437ffe6))
 
   template  constexpr auto
   impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash>{} (hb_deref (v)))
@@ -551,6 +684,8 @@
 template  static inline hb_pair_t
 hb_pair (T1&& a, T2&& b) { return hb_pair_t (a, b); }
 
+typedef hb_pair_t hb_codepoint_pair_t;
+
 struct
 {
   template  constexpr typename Pair::first_t
@@ -626,8 +761,10 @@
 
   if (sizeof (T) == 8)
   {
-    unsigned int shift = 32;
-    return hb_popcount ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
+    uint64_t y = (uint64_t) v;
+    y -= ((y >> 1) & 0x5555555555555555ull);
+    y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull);
+    return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56;
   }
 
   if (sizeof (T) == 16)
@@ -851,7 +988,7 @@
 hb_memset (void *s, int c, unsigned int n)
 {
   /* It's illegal to pass NULL to memset(), even if n is zero. */
-  if (unlikely (!n)) return 0;
+  if (unlikely (!n)) return s;
   return memset (s, c, n);
 }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-array.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-array.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-array.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-array.hh	2024-01-16 16:19:00.000000000 +0000
@@ -75,11 +75,25 @@
    */
   typedef Type& __item_t__;
   static constexpr bool is_random_access_iterator = true;
+  static constexpr bool has_fast_len = true;
+  Type& __item__ () const
+  {
+    if (unlikely (!length)) return CrapOrNull (Type);
+    return *arrayZ;
+  }
   Type& __item_at__ (unsigned i) const
   {
     if (unlikely (i >= length)) return CrapOrNull (Type);
     return arrayZ[i];
   }
+  void __next__ ()
+  {
+    if (unlikely (!length))
+      return;
+    length--;
+    backwards_length++;
+    arrayZ++;
+  }
   void __forward__ (unsigned n)
   {
     if (unlikely (n > length))
@@ -88,6 +102,14 @@
     backwards_length += n;
     arrayZ += n;
   }
+  void __prev__ ()
+  {
+    if (unlikely (!backwards_length))
+      return;
+    length++;
+    backwards_length--;
+    arrayZ--;
+  }
   void __rewind__ (unsigned n)
   {
     if (unlikely (n > backwards_length))
@@ -122,9 +144,14 @@
 
   uint32_t hash () const
   {
-    uint32_t current = 0;
+    // FNV-1a hash function
+    // https://github.com/harfbuzz/harfbuzz/pull/4228
+    uint32_t current = /*cbf29ce4*/0x84222325;
     for (auto &v : *this)
-      current = current * 31 + hb_hash (v);
+    {
+      current = current ^ hb_hash (v);
+      current = current * 16777619;
+    }
     return current;
   }
 
@@ -322,6 +349,7 @@
   HB_ITER_USING (iter_base_t);
   static constexpr bool is_random_access_iterator = true;
   static constexpr bool is_sorted_iterator = true;
+  static constexpr bool has_fast_len = true;
 
   hb_sorted_array_t () = default;
   hb_sorted_array_t (const hb_sorted_array_t&) = default;
@@ -449,41 +477,21 @@
 
 /* Specialize hash() for byte arrays. */
 
+#ifndef HB_OPTIMIZE_SIZE_MORE
 template <>
 inline uint32_t hb_array_t::hash () const
 {
-  uint32_t current = 0;
-  unsigned i = 0;
-
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
-  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
-  for (; i + 4 <= this->length; i += 4)
-    current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
-#endif
-
-  for (; i < this->length; i++)
-    current = current * 31 + hb_hash (this->arrayZ[i]);
-  return current;
+  // https://github.com/harfbuzz/harfbuzz/pull/4228
+  return fasthash32(arrayZ, length, 0xf437ffe6 /* magic? */);
 }
 
 template <>
 inline uint32_t hb_array_t::hash () const
 {
-  uint32_t current = 0;
-  unsigned i = 0;
-
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
-  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
-  for (; i + 4 <= this->length; i += 4)
-    current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
-#endif
-
-  for (; i < this->length; i++)
-    current = current * 31 + hb_hash (this->arrayZ[i]);
-  return current;
+  // https://github.com/harfbuzz/harfbuzz/pull/4228
+  return fasthash32(arrayZ, length, 0xf437ffe6 /* magic? */);
 }
+#endif
 
 
 typedef hb_array_t hb_bytes_t;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh	2024-01-16 16:19:00.000000000 +0000
@@ -204,6 +204,7 @@
 
   hb_atomic_ptr_t () = default;
   constexpr hb_atomic_ptr_t (T* v) : v (v) {}
+  hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete;
 
   void init (T* v_ = nullptr) { set_relaxed (v_); }
   void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh	2024-01-16 16:19:00.000000000 +0000
@@ -39,10 +39,10 @@
     back_map.reset ();
   }
 
-  void resize (unsigned pop)
+  void alloc (unsigned pop)
   {
-    forw_map.resize (pop);
-    back_map.resize (pop);
+    forw_map.alloc (pop);
+    back_map.alloc (pop);
   }
 
   bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
@@ -83,7 +83,6 @@
 
   unsigned int get_population () const { return forw_map.get_population (); }
 
-
   protected:
   hb_map_t  forw_map;
   hb_map_t  back_map;
@@ -94,9 +93,31 @@
   auto iter () const HB_AUTO_RETURN (+ forw_map.iter())
 };
 
-/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
-struct hb_inc_bimap_t : hb_bimap_t
+/* Incremental bimap: only lhs is given, rhs is incrementally assigned */
+struct hb_inc_bimap_t
 {
+  bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
+
+  unsigned int get_population () const { return forw_map.get_population (); }
+
+  void reset ()
+  {
+    forw_map.reset ();
+    back_map.reset ();
+  }
+
+  void alloc (unsigned pop)
+  {
+    forw_map.alloc (pop);
+    back_map.alloc (pop);
+  }
+
+  void clear ()
+  {
+    forw_map.clear ();
+    back_map.resize (0);
+  }
+
   /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
    * Return the rhs value as the result.
    */
@@ -105,32 +126,42 @@
     hb_codepoint_t  rhs = forw_map[lhs];
     if (rhs == HB_MAP_VALUE_INVALID)
     {
-      rhs = next_value++;
-      set (lhs, rhs);
+      rhs = back_map.length;
+      forw_map.set (lhs, rhs);
+      back_map.push (lhs);
     }
     return rhs;
   }
 
   hb_codepoint_t skip ()
-  { return next_value++; }
+  {
+    hb_codepoint_t start = back_map.length;
+    back_map.push (HB_MAP_VALUE_INVALID);
+    return start;
+  }
 
   hb_codepoint_t skip (unsigned count)
-  { return next_value += count; }
+  {
+    hb_codepoint_t start = back_map.length;
+    back_map.alloc (back_map.length + count);
+    for (unsigned i = 0; i < count; i++)
+      back_map.push (HB_MAP_VALUE_INVALID);
+    return start;
+  }
 
   hb_codepoint_t get_next_value () const
-  { return next_value; }
+  { return back_map.length; }
 
   void add_set (const hb_set_t *set)
   {
-    hb_codepoint_t i = HB_SET_VALUE_INVALID;
-    while (hb_set_next (set, &i)) add (i);
+    for (auto i : *set) add (i);
   }
 
   /* Create an identity map. */
   bool identity (unsigned int size)
   {
     clear ();
-    for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
+    for (hb_codepoint_t i = 0; i < size; i++) add (i);
     return !in_error ();
   }
 
@@ -145,20 +176,30 @@
   {
     hb_codepoint_t  count = get_population ();
     hb_vector_t  work;
-    work.resize (count);
+    if (unlikely (!work.resize (count, false))) return;
 
     for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
-      work[rhs] = back_map[rhs];
+      work.arrayZ[rhs] = back_map[rhs];
 
     work.qsort (cmp_id);
 
     clear ();
     for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
-      set (work[rhs], rhs);
+      add (work.arrayZ[rhs]);
   }
 
+  hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
+  hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map[rhs]; }
+
+  hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
+  bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); }
+
   protected:
-  unsigned int next_value = 0;
+  hb_map_t forw_map;
+  hb_vector_t back_map;
+
+  public:
+  auto keys () const HB_AUTO_RETURN (+ back_map.iter())
 };
 
 #endif /* HB_BIMAP_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh	2024-01-16 16:19:00.000000000 +0000
@@ -89,14 +89,18 @@
 
 struct hb_bit_page_t
 {
-  void init0 () { v.init0 (); }
-  void init1 () { v.init1 (); }
+  void init0 () { v.init0 (); population = 0; }
+  void init1 () { v.init1 (); population = PAGE_BITS; }
+
+  void dirty () { population = UINT_MAX; }
 
   static inline constexpr unsigned len ()
   { return ARRAY_LENGTH_CONST (v); }
 
+  operator bool () const { return !is_empty (); }
   bool is_empty () const
   {
+    if (has_population ()) return !population;
     return
     + hb_iter (v)
     | hb_none
@@ -104,14 +108,11 @@
   }
   uint32_t hash () const
   {
-    return
-    + hb_iter (v)
-    | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u)
-    ;
+    return hb_bytes_t ((const char *) &v, sizeof (v)).hash ();
   }
 
-  void add (hb_codepoint_t g) { elt (g) |= mask (g); }
-  void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
+  void add (hb_codepoint_t g) { elt (g) |= mask (g); dirty (); }
+  void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); }
   void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); }
   bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
 
@@ -123,20 +124,21 @@
       *la |= (mask (b) << 1) - mask(a);
     else
     {
-      *la |= ~(mask (a) - 1);
+      *la |= ~(mask (a) - 1llu);
       la++;
 
       hb_memset (la, 0xff, (char *) lb - (char *) la);
 
-      *lb |= ((mask (b) << 1) - 1);
+      *lb |= ((mask (b) << 1) - 1llu);
     }
+    dirty ();
   }
   void del_range (hb_codepoint_t a, hb_codepoint_t b)
   {
     elt_t *la = &elt (a);
     elt_t *lb = &elt (b);
     if (la == lb)
-      *la &= ~((mask (b) << 1) - mask(a));
+      *la &= ~((mask (b) << 1llu) - mask(a));
     else
     {
       *la &= mask (a) - 1;
@@ -144,8 +146,9 @@
 
       hb_memset (la, 0, (char *) lb - (char *) la);
 
-      *lb &= ~((mask (b) << 1) - 1);
+      *lb &= ~((mask (b) << 1) - 1llu);
     }
+    dirty ();
   }
   void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v)
   { if (v) add_range (a, b); else del_range (a, b); }
@@ -216,6 +219,7 @@
     return count;
   }
 
+  bool operator == (const hb_bit_page_t &other) const { return is_equal (other); }
   bool is_equal (const hb_bit_page_t &other) const
   {
     for (unsigned i = 0; i < len (); i++)
@@ -223,20 +227,28 @@
         return false;
     return true;
   }
+  bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); }
   bool is_subset (const hb_bit_page_t &larger_page) const
   {
+    if (has_population () && larger_page.has_population () &&
+        population > larger_page.population)
+      return false;
+
     for (unsigned i = 0; i < len (); i++)
       if (~larger_page.v[i] & v[i])
         return false;
     return true;
   }
 
+  bool has_population () const { return population != UINT_MAX; }
   unsigned int get_population () const
   {
-    return
+    if (has_population ()) return population;
+    population =
     + hb_iter (v)
     | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u)
     ;
+    return population;
   }
 
   bool next (hb_codepoint_t *codepoint) const
@@ -332,9 +344,9 @@
   const elt_t& elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
   static constexpr elt_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); }
 
+  mutable unsigned population;
   vector_t v;
 };
-static_assert (hb_bit_page_t::PAGE_BITS == sizeof (hb_bit_page_t) * 8, "");
 
 
 #endif /* HB_BIT_PAGE_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh	2024-01-16 16:19:00.000000000 +0000
@@ -136,7 +136,7 @@
   /* Sink interface. */
   hb_bit_set_invertible_t& operator << (hb_codepoint_t v)
   { add (v); return *this; }
-  hb_bit_set_invertible_t& operator << (const hb_pair_t& range)
+  hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range)
   { add_range (range.first, range.second); return *this; }
 
   bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
@@ -162,7 +162,7 @@
       auto it1 = iter ();
       auto it2 = other.iter ();
       return hb_all (+ hb_zip (it1, it2)
-                     | hb_map ([](hb_pair_t _) { return _.first == _.second; }));
+                     | hb_map ([](hb_codepoint_pair_t _) { return _.first == _.second; }));
     }
   }
 
@@ -345,6 +345,7 @@
   struct iter_t : hb_iter_with_fallback_t
   {
     static constexpr bool is_sorted_iterator = true;
+    static constexpr bool has_fast_len = true;
     iter_t (const hb_bit_set_invertible_t &s_ = Null (hb_bit_set_invertible_t),
             bool init = true) : s (&s_), v (INVALID), l(0)
     {
@@ -363,7 +364,7 @@
     unsigned __len__ () const { return l; }
     iter_t end () const { return iter_t (*s, false); }
     bool operator != (const iter_t& o) const
-    { return s != o.s || v != o.v; }
+    { return v != o.v || s != o.s; }
 
     protected:
     const hb_bit_set_invertible_t *s;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh	2024-01-16 16:19:00.000000000 +0000
@@ -30,7 +30,6 @@
 
 #include "hb.hh"
 #include "hb-bit-page.hh"
-#include "hb-machinery.hh"
 
 
 struct hb_bit_set_t
@@ -134,7 +133,11 @@
   {
     uint32_t h = 0;
     for (auto &map : page_map)
-      h = h * 31 + hb_hash (map.major) + hb_hash (pages[map.index]);
+    {
+      auto &page = pages.arrayZ[map.index];
+      if (unlikely (page.is_empty ())) continue;
+      h = h * 31 + hb_hash (map.major) + hb_hash (page);
+    }
     return h;
   }
 
@@ -179,6 +182,16 @@
     return true;
   }
 
+  /* Duplicated here from hb-machinery.hh to avoid including it. */
+  template
+  static inline const Type& StructAtOffsetUnaligned(const void *P, unsigned int offset)
+  {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+    return * reinterpret_cast ((const char *) P + offset);
+#pragma GCC diagnostic pop
+  }
+
   template 
   void set_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T))
   {
@@ -342,7 +355,7 @@
   /* Sink interface. */
   hb_bit_set_t& operator << (hb_codepoint_t v)
   { add (v); return *this; }
-  hb_bit_set_t& operator << (const hb_pair_t& range)
+  hb_bit_set_t& operator << (const hb_codepoint_pair_t& range)
   { add_range (range.first, range.second); return *this; }
 
   bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
@@ -402,7 +415,6 @@
       uint32_t spm = page_map[spi].major;
       uint32_t lpm = larger_set.page_map[lpi].major;
       auto sp = page_at (spi);
-      auto lp = larger_set.page_at (lpi);
 
       if (spm < lpm && !sp.is_empty ())
         return false;
@@ -410,6 +422,7 @@
       if (lpm < spm)
         continue;
 
+      auto lp = larger_set.page_at (lpi);
       if (!sp.is_subset (lp))
         return false;
 
@@ -549,6 +562,7 @@
         count--;
         page_map.arrayZ[count] = page_map.arrayZ[a];
         page_at (count).v = op (page_at (a).v, other.page_at (b).v);
+        page_at (count).dirty ();
       }
       else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major)
       {
@@ -567,7 +581,7 @@
           count--;
           page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
           page_map.arrayZ[count].index = next_page++;
-          page_at (count).v = other.page_at (b).v;
+          page_at (count) = other.page_at (b);
         }
       }
     }
@@ -585,7 +599,7 @@
         count--;
         page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
         page_map.arrayZ[count].index = next_page++;
-        page_at (count).v = other.page_at (b).v;
+        page_at (count) = other.page_at (b);
       }
     assert (!count);
     resize (newCount);
@@ -623,6 +637,7 @@
         *codepoint = INVALID;
         return false;
       }
+      last_page_lookup = i;
     }
 
     const auto* pages_array = pages.arrayZ;
@@ -632,7 +647,6 @@
       if (pages_array[current.index].next (codepoint))
       {
         *codepoint += current.major * page_t::PAGE_BITS;
-        last_page_lookup = i;
         return true;
       }
       i++;
@@ -649,7 +663,6 @@
         return true;
       }
     }
-    last_page_lookup = 0;
     *codepoint = INVALID;
     return false;
   }
@@ -863,6 +876,7 @@
   struct iter_t : hb_iter_with_fallback_t
   {
     static constexpr bool is_sorted_iterator = true;
+    static constexpr bool has_fast_len = true;
     iter_t (const hb_bit_set_t &s_ = Null (hb_bit_set_t),
             bool init = true) : s (&s_), v (INVALID), l(0)
     {
@@ -899,7 +913,7 @@
 
     /* The extra page_map length is necessary; can't just rely on vector here,
      * since the next check would be tricked because a null page also has
-     * major==0, which we can't distinguish from an actualy major==0 page... */
+     * major==0, which we can't distinguish from an actually major==0 page... */
     unsigned i = last_page_lookup;
     if (likely (i < page_map.length))
     {
@@ -921,7 +935,7 @@
       memmove (page_map.arrayZ + i + 1,
                page_map.arrayZ + i,
                (page_map.length - 1 - i) * page_map.item_size);
-      page_map[i] = map;
+      page_map.arrayZ[i] = map;
     }
 
     last_page_lookup = i;
@@ -933,7 +947,7 @@
 
     /* The extra page_map length is necessary; can't just rely on vector here,
      * since the next check would be tricked because a null page also has
-     * major==0, which we can't distinguish from an actualy major==0 page... */
+     * major==0, which we can't distinguish from an actually major==0 page... */
     unsigned i = last_page_lookup;
     if (likely (i < page_map.length))
     {
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh	2024-01-16 16:19:00.000000000 +0000
@@ -32,7 +32,7 @@
 #include "hb.hh"
 
 
-#line 33 "hb-buffer-deserialize-json.hh"
+#line 36 "hb-buffer-deserialize-json.hh"
 static const unsigned char _deserialize_json_trans_keys[] = {
         0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
         48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
@@ -555,12 +555,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
 
-#line 552 "hb-buffer-deserialize-json.hh"
+#line 559 "hb-buffer-deserialize-json.hh"
         {
         cs = deserialize_json_start;
         }
 
-#line 555 "hb-buffer-deserialize-json.hh"
+#line 564 "hb-buffer-deserialize-json.hh"
         {
         int _slen;
         int _trans;
@@ -772,7 +772,7 @@
         *end_ptr = p;
 }
         break;
-#line 733 "hb-buffer-deserialize-json.hh"
+#line 776 "hb-buffer-deserialize-json.hh"
         }
 
 _again:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh	2024-01-16 16:19:00.000000000 +0000
@@ -32,7 +32,7 @@
 #include "hb.hh"
 
 
-#line 33 "hb-buffer-deserialize-text-glyphs.hh"
+#line 36 "hb-buffer-deserialize-text-glyphs.hh"
 static const unsigned char _deserialize_text_glyphs_trans_keys[] = {
         0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
         48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u,
@@ -349,12 +349,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
 
-#line 346 "hb-buffer-deserialize-text-glyphs.hh"
+#line 353 "hb-buffer-deserialize-text-glyphs.hh"
         {
         cs = deserialize_text_glyphs_start;
         }
 
-#line 349 "hb-buffer-deserialize-text-glyphs.hh"
+#line 358 "hb-buffer-deserialize-text-glyphs.hh"
         {
         int _slen;
         int _trans;
@@ -550,7 +550,7 @@
         *end_ptr = p;
 }
         break;
-#line 516 "hb-buffer-deserialize-text-glyphs.hh"
+#line 554 "hb-buffer-deserialize-text-glyphs.hh"
         }
 
 _again:
@@ -667,7 +667,7 @@
         *end_ptr = p;
 }
         break;
-#line 616 "hb-buffer-deserialize-text-glyphs.hh"
+#line 671 "hb-buffer-deserialize-text-glyphs.hh"
         }
         }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh	2024-01-16 16:19:00.000000000 +0000
@@ -32,7 +32,7 @@
 #include "hb.hh"
 
 
-#line 33 "hb-buffer-deserialize-text-unicode.hh"
+#line 36 "hb-buffer-deserialize-text-unicode.hh"
 static const unsigned char _deserialize_text_unicode_trans_keys[] = {
         0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u,
         9u, 124u, 0
@@ -197,12 +197,12 @@
   hb_glyph_info_t info = {0};
   const hb_glyph_position_t pos = {0};
 
-#line 194 "hb-buffer-deserialize-text-unicode.hh"
+#line 201 "hb-buffer-deserialize-text-unicode.hh"
         {
         cs = deserialize_text_unicode_start;
         }
 
-#line 197 "hb-buffer-deserialize-text-unicode.hh"
+#line 206 "hb-buffer-deserialize-text-unicode.hh"
         {
         int _slen;
         int _trans;
@@ -269,7 +269,7 @@
         *end_ptr = p;
 }
         break;
-#line 256 "hb-buffer-deserialize-text-unicode.hh"
+#line 273 "hb-buffer-deserialize-text-unicode.hh"
         }
 
 _again:
@@ -307,7 +307,7 @@
         *end_ptr = p;
 }
         break;
-#line 289 "hb-buffer-deserialize-text-unicode.hh"
+#line 311 "hb-buffer-deserialize-text-unicode.hh"
         }
         }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc	2024-01-16 16:19:00.000000000 +0000
@@ -162,14 +162,8 @@
     hb_buffer_set_flags (fragment, flags);
 
     hb_buffer_append (fragment, text_buffer, text_start, text_end);
-    if (!hb_shape_full (font, fragment, features, num_features, shapers))
-    {
-      buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
-      hb_buffer_destroy (reconstruction);
-      hb_buffer_destroy (fragment);
-      return false;
-    }
-    else if (!fragment->successful || fragment->shaping_failed)
+    if (!hb_shape_full (font, fragment, features, num_features, shapers) ||
+        fragment->successful || fragment->shaping_failed)
     {
       hb_buffer_destroy (reconstruction);
       hb_buffer_destroy (fragment);
@@ -185,15 +179,18 @@
   }
 
   bool ret = true;
-  hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
-  if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+  if (likely (reconstruction->successful))
   {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
-    ret = false;
+    hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
+    if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+    {
+      buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
+      ret = false;
 
-    /* Return the reconstructed result instead so it can be inspected. */
-    hb_buffer_set_length (buffer, 0);
-    hb_buffer_append (buffer, reconstruction, 0, -1);
+      /* Return the reconstructed result instead so it can be inspected. */
+      hb_buffer_set_length (buffer, 0);
+      hb_buffer_append (buffer, reconstruction, 0, -1);
+    }
   }
 
   hb_buffer_destroy (reconstruction);
@@ -316,28 +313,13 @@
   /*
    * Shape the two fragment streams.
    */
-  if (!hb_shape_full (font, fragments[0], features, num_features, shapers))
-  {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
-    ret = false;
-    goto out;
-  }
-  else if (!fragments[0]->successful || fragments[0]->shaping_failed)
-  {
-    ret = true;
-    goto out;
-  }
-  if (!hb_shape_full (font, fragments[1], features, num_features, shapers))
-  {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
-    ret = false;
+  if (!hb_shape_full (font, fragments[0], features, num_features, shapers) ||
+      !fragments[0]->successful || fragments[0]->shaping_failed)
     goto out;
-  }
-  else if (!fragments[1]->successful || fragments[1]->shaping_failed)
-  {
-    ret = true;
+
+  if (!hb_shape_full (font, fragments[1], features, num_features, shapers) ||
+      !fragments[1]->successful || fragments[1]->shaping_failed)
     goto out;
-  }
 
   if (!forward)
   {
@@ -377,21 +359,23 @@
     hb_buffer_reverse (reconstruction);
   }
 
-  /*
-   * Diff results.
-   */
-  diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
-  if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+  if (likely (reconstruction->successful))
   {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
-    ret = false;
+    /*
+     * Diff results.
+     */
+    diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
+    if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+    {
+      buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
+      ret = false;
 
-    /* Return the reconstructed result instead so it can be inspected. */
-    hb_buffer_set_length (buffer, 0);
-    hb_buffer_append (buffer, reconstruction, 0, -1);
+      /* Return the reconstructed result instead so it can be inspected. */
+      hb_buffer_set_length (buffer, 0);
+      hb_buffer_append (buffer, reconstruction, 0, -1);
+    }
   }
 
-
 out:
   hb_buffer_destroy (reconstruction);
   hb_buffer_destroy (fragments[0]);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc	2024-01-16 16:19:00.000000000 +0000
@@ -268,7 +268,7 @@
   unicode = hb_unicode_funcs_reference (src.unicode);
   flags = src.flags;
   cluster_level = src.cluster_level;
-  replacement = src.invisible;
+  replacement = src.replacement;
   invisible = src.invisible;
   not_found = src.not_found;
 }
@@ -499,12 +499,12 @@
                         unsigned int cluster_start,
                         unsigned int cluster_end)
 {
-  hb_mask_t not_mask = ~mask;
-  value &= mask;
-
   if (!mask)
     return;
 
+  hb_mask_t not_mask = ~mask;
+  value &= mask;
+
   unsigned int count = len;
   for (unsigned int i = 0; i < count; i++)
     if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
@@ -1327,7 +1327,7 @@
  * Sets the #hb_codepoint_t that replaces characters not found in
  * the font during shaping.
  *
- * The not-found glyph defaults to zero, sometimes knows as the
+ * The not-found glyph defaults to zero, sometimes known as the
  * ".notdef" glyph.  This API allows for differentiating the two.
  *
  * Since: 3.1.0
@@ -2076,7 +2076,7 @@
  * hb_buffer_diff:
  * @buffer: a buffer.
  * @reference: other buffer to compare to.
- * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1.
+ * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepoint_t) -1.
  * @position_fuzz: allowed absolute difference in position values.
  *
  * If dottedcircle_glyph is (hb_codepoint_t) -1 then #HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer.h	2024-01-16 16:19:00.000000000 +0000
@@ -99,7 +99,7 @@
  *                                 layout, by avoiding re-shaping of each line
  *                                 after line-breaking, by limiting the
  *                                 reshaping to a small piece around the
- *                                 breaking positin only, even if the breaking
+ *                                 breaking position only, even if the breaking
  *                                 position carries the
  *                                 #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when
  *                                 hyphenation or other text transformation
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh	2024-01-16 16:19:00.000000000 +0000
@@ -464,13 +464,16 @@
                       start, end,
                       true);
   }
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
   {
     if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
       return;
     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
                       start, end,
-                      true);
+                      false);
   }
   void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
   {
@@ -478,6 +481,9 @@
                       start, end,
                       true, true);
   }
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
   {
     if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
@@ -493,6 +499,13 @@
 
   HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size);
 
+  HB_NODISCARD bool resize (unsigned length)
+  {
+    assert (!have_output);
+    if (unlikely (!ensure (length))) return false;
+    len = length;
+    return true;
+  }
   HB_NODISCARD bool ensure (unsigned int size)
   { return likely (!size || size < allocated) ? true : enlarge (size); }
 
@@ -553,7 +566,7 @@
   bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
   {
 #ifdef HB_NO_BUFFER_MESSAGE
-   return true;
+    return true;
 #else
     if (likely (!messaging ()))
       return true;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-cache.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-cache.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-cache.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-cache.hh	2024-01-16 16:19:00.000000000 +0000
@@ -62,14 +62,12 @@
   static_assert ((key_bits >= cache_bits), "");
   static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
 
-  hb_cache_t () { init (); }
-
-  void init () { clear (); }
+  hb_cache_t () { clear (); }
 
   void clear ()
   {
-    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
-      values[i] = -1;
+    for (auto &v : values)
+      v = -1;
   }
 
   bool get (unsigned int key, unsigned int *value) const
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -26,6 +26,8 @@
 #ifndef HB_CFF_INTERP_COMMON_HH
 #define HB_CFF_INTERP_COMMON_HH
 
+extern HB_INTERNAL const unsigned char *endchar_str;
+
 namespace CFF {
 
 using namespace OT;
@@ -336,8 +338,6 @@
   hb_ubytes_t       str;
 };
 
-using byte_str_array_t = hb_vector_t;
-
 /* stack */
 template 
 struct cff_stack_t
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -883,14 +883,12 @@
 
     unsigned max_ops = HB_CFF_MAX_OPS;
     for (;;) {
-      if (unlikely (!--max_ops))
+      OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
+      if (unlikely (SUPER::env.in_error () || !--max_ops))
       {
         SUPER::env.set_error ();
-        break;
-      }
-      OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
-      if (unlikely (SUPER::env.in_error ()))
         return false;
+      }
       if (SUPER::env.is_endchar ())
         break;
     }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-common.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-common.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-common.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-common.cc	2024-01-16 16:19:00.000000000 +0000
@@ -815,7 +815,7 @@
   }
 
   const char *p = *pp;
-  while (*pp < end && (ISALNUM(**pp) || **pp == '_'))
+  while (*pp < end && (**pp != ' ' && **pp != '=' && **pp != '[' && **pp != quote))
     (*pp)++;
 
   if (p == *pp || *pp - p > 4)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-common.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-common.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-common.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-common.h	2024-01-16 16:19:00.000000000 +0000
@@ -104,6 +104,16 @@
  *
  **/
 typedef uint32_t hb_codepoint_t;
+
+/**
+ * HB_CODEPOINT_INVALID:
+ *
+ * Unused #hb_codepoint_t value.
+ *
+ * Since: 8.0.0
+ */
+#define HB_CODEPOINT_INVALID ((hb_codepoint_t) -1)
+
 /**
  * hb_position_t:
  *
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-config.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-config.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-config.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-config.hh	2024-01-16 16:19:00.000000000 +0000
@@ -44,14 +44,14 @@
 #ifdef HB_TINY
 #define HB_LEAN
 #define HB_MINI
+#define HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE_MORE
+#define HB_MINIMIZE_MEMORY_USAGE
 #define HB_NO_MT
 #define HB_NO_UCD_UNASSIGNED
 #ifndef NDEBUG
 #define NDEBUG
 #endif
-#ifndef __OPTIMIZE_SIZE__
-#define __OPTIMIZE_SIZE__
-#endif
 #endif
 
 #ifdef HB_LEAN
@@ -97,6 +97,12 @@
 #define HB_NO_BORING_EXPANSION
 #endif
 
+#ifdef __OPTIMIZE_SIZE__
+#ifndef HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE
+#endif
+#endif
+
 #if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H)
 #ifndef HB_CONFIG_OVERRIDE_H
 #define HB_CONFIG_OVERRIDE_H "config-override.h"
@@ -108,7 +114,8 @@
 
 #ifdef HB_NO_BORING_EXPANSION
 #define HB_NO_BEYOND_64K
-#define HB_NO_AVAR2
+#define HB_NO_CUBIC_GLYF
+#define HB_NO_VAR_COMPOSITES
 #endif
 
 #ifdef HB_DISABLE_DEPRECATED
@@ -175,21 +182,27 @@
 #define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
 #endif
 
-#ifdef NDEBUG
-#ifndef HB_NDEBUG
-#define HB_NDEBUG
-#endif
+#ifdef HB_OPTIMIZE_SIZE_MORE
+#define HB_NO_OT_RULESETS_FAST_PATH
 #endif
 
-#ifdef __OPTIMIZE_SIZE__
-#ifndef HB_OPTIMIZE_SIZE
-#define HB_OPTIMIZE_SIZE
-#endif
+#ifdef HB_MINIMIZE_MEMORY_USAGE
+#define HB_NO_GDEF_CACHE
+#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
+#define HB_NO_OT_FONT_ADVANCE_CACHE
+#define HB_NO_OT_FONT_CMAP_CACHE
 #endif
 
 #ifdef HB_OPTIMIZE_SIZE
-#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
+#define HB_OPTIMIZE_SIZE_VAL 1
+#else
+#define HB_OPTIMIZE_SIZE_VAL 0
 #endif
 
+#ifdef HB_MINIMIZE_MEMORY_USAGE
+#define HB_MINIMIZE_MEMORY_USAGE_VAL 1
+#else
+#define HB_MINIMIZE_MEMORY_USAGE_VAL 0
+#endif
 
 #endif /* HB_CONFIG_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-debug.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-debug.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-debug.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-debug.hh	2024-01-16 16:19:00.000000000 +0000
@@ -265,8 +265,9 @@
   }
 }
 template <>
-/*static*/ inline void _hb_warn_no_return (bool returned HB_UNUSED)
-{}
+/*static*/ inline void _hb_warn_no_return (bool returned HB_UNUSED) {}
+template <>
+/*static*/ inline void _hb_warn_no_return (bool returned HB_UNUSED) {}
 
 template 
 struct hb_auto_trace_t
@@ -389,6 +390,10 @@
 #define HB_DEBUG_UNISCRIBE (HB_DEBUG+0)
 #endif
 
+#ifndef HB_DEBUG_WASM
+#define HB_DEBUG_WASM (HB_DEBUG+0)
+#endif
+
 /*
  * With tracing.
  */
@@ -446,12 +451,26 @@
 #define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0)
 #endif
 
+#ifndef HB_DEBUG_PAINT
+#define HB_DEBUG_PAINT (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_PAINT
+#define TRACE_PAINT(this) \
+  HB_UNUSED hb_auto_trace_t trace \
+  (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+   " ")
+#else
+#define TRACE_PAINT(this) HB_UNUSED hb_no_trace_t trace
+#endif
+
+
 #ifndef HB_DEBUG_DISPATCH
 #define HB_DEBUG_DISPATCH ( \
         HB_DEBUG_APPLY + \
         HB_DEBUG_SANITIZE + \
         HB_DEBUG_SERIALIZE + \
         HB_DEBUG_SUBSET + \
+        HB_DEBUG_PAINT + \
         0)
 #endif
 #if HB_DEBUG_DISPATCH
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h	2024-01-16 16:19:00.000000000 +0000
@@ -255,6 +255,52 @@
 hb_font_get_glyph_v_kerning (hb_font_t *font,
                              hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
 
+
+/**
+ * hb_font_get_glyph_shape_func_t:
+ * @font: #hb_font_t to work upon
+ * @font_data: @font user data pointer
+ * @glyph: The glyph ID to query
+ * @draw_funcs: The draw functions to send the shape data to
+ * @draw_data: The data accompanying the draw functions
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * Since: 4.0.0
+ * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead
+ **/
+typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
+                                                hb_codepoint_t glyph,
+                                                hb_draw_funcs_t *draw_funcs, void *draw_data,
+                                                void *user_data);
+
+/**
+ * hb_font_funcs_set_glyph_shape_func:
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets the implementation function for #hb_font_get_glyph_shape_func_t,
+ * which is the same as #hb_font_draw_glyph_func_t.
+ *
+ * Since: 4.0.0
+ * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead
+ **/
+HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_func)
+HB_EXTERN void
+hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
+                                    hb_font_get_glyph_shape_func_t func,
+                                    void *user_data, hb_destroy_func_t destroy);
+
+HB_DEPRECATED_FOR (hb_font_draw_glyph)
+HB_EXTERN void
+hb_font_get_glyph_shape (hb_font_t *font,
+                         hb_codepoint_t glyph,
+                         hb_draw_funcs_t *dfuncs, void *draw_data);
+
+
 #endif
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-draw.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-draw.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-draw.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-draw.hh	2024-01-16 16:19:00.000000000 +0000
@@ -93,50 +93,57 @@
                      !user_data ? nullptr : user_data->close_path); }
 
 
-  void move_to (void *draw_data, hb_draw_state_t &st,
-                float to_x, float to_y)
+  void
+  HB_ALWAYS_INLINE
+  move_to (void *draw_data, hb_draw_state_t &st,
+           float to_x, float to_y)
   {
-    if (st.path_open) close_path (draw_data, st);
+    if (unlikely (st.path_open)) close_path (draw_data, st);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
-  void line_to (void *draw_data, hb_draw_state_t &st,
-                float to_x, float to_y)
+  void
+  HB_ALWAYS_INLINE
+  line_to (void *draw_data, hb_draw_state_t &st,
+           float to_x, float to_y)
   {
-    if (!st.path_open) start_path (draw_data, st);
+    if (unlikely (!st.path_open)) start_path (draw_data, st);
     emit_line_to (draw_data, st, to_x, to_y);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
   void
+  HB_ALWAYS_INLINE
   quadratic_to (void *draw_data, hb_draw_state_t &st,
                 float control_x, float control_y,
                 float to_x, float to_y)
   {
-    if (!st.path_open) start_path (draw_data, st);
+    if (unlikely (!st.path_open)) start_path (draw_data, st);
     emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
   void
+  HB_ALWAYS_INLINE
   cubic_to (void *draw_data, hb_draw_state_t &st,
             float control1_x, float control1_y,
             float control2_x, float control2_y,
             float to_x, float to_y)
   {
-    if (!st.path_open) start_path (draw_data, st);
+    if (unlikely (!st.path_open)) start_path (draw_data, st);
     emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
   void
+  HB_ALWAYS_INLINE
   close_path (void *draw_data, hb_draw_state_t &st)
   {
-    if (st.path_open)
+    if (likely (st.path_open))
     {
       if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
         emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
@@ -168,6 +175,7 @@
 
   ~hb_draw_session_t () { close_path (); }
 
+  HB_ALWAYS_INLINE
   void move_to (float to_x, float to_y)
   {
     if (likely (not_slanted))
@@ -177,6 +185,7 @@
       funcs->move_to (draw_data, st,
                       to_x + to_y * slant, to_y);
   }
+  HB_ALWAYS_INLINE
   void line_to (float to_x, float to_y)
   {
     if (likely (not_slanted))
@@ -187,6 +196,7 @@
                       to_x + to_y * slant, to_y);
   }
   void
+  HB_ALWAYS_INLINE
   quadratic_to (float control_x, float control_y,
                 float to_x, float to_y)
   {
@@ -200,6 +210,7 @@
                            to_x + to_y * slant, to_y);
   }
   void
+  HB_ALWAYS_INLINE
   cubic_to (float control1_x, float control1_y,
             float control2_x, float control2_y,
             float to_x, float to_y)
@@ -215,6 +226,7 @@
                        control2_x + control2_y * slant, control2_y,
                        to_x + to_y * slant, to_y);
   }
+  HB_ALWAYS_INLINE
   void close_path ()
   {
     funcs->close_path (draw_data, st);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-font.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-font.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-font.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-font.cc	2024-01-16 16:19:00.000000000 +0000
@@ -1066,7 +1066,7 @@
  * @glyph_stride: The stride between successive glyph IDs
  *
  * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph
- * IDs must be returned in a #hb_codepoint_t output parameter. Stopes at the
+ * IDs must be returned in a #hb_codepoint_t output parameter. Stops at the
  * first unsupported glyph ID.
  *
  * Return value: the number of code points processed
@@ -1389,6 +1389,7 @@
   return font->get_glyph_from_name (name, len, glyph);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_font_get_glyph_shape:
  * @font: #hb_font_t to work upon
@@ -1410,6 +1411,7 @@
 {
   hb_font_draw_glyph (font, glyph, dfuncs, draw_data);
 }
+#endif
 
 /**
  * hb_font_draw_glyph:
@@ -2648,7 +2650,6 @@
       if (axes[axis_index].axisTag == tag)
         design_coords[axis_index] = v;
   }
-  font->face->table.avar->map_coords (normalized, coords_length);
 
   hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
@@ -2720,8 +2721,6 @@
     if (axes[axis_index].axisTag == tag)
       design_coords[axis_index] = value;
 
-  font->face->table.avar->map_coords (normalized, coords_length);
-
   hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
 
@@ -3058,6 +3057,7 @@
 #endif
 
 
+#ifndef HB_DISABLE_DEPRECATED
 void
 hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t               *ffuncs,
                                    hb_font_get_glyph_shape_func_t  func,
@@ -3066,3 +3066,4 @@
 {
   hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy);
 }
+#endif
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-font.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-font.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-font.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-font.h	2024-01-16 16:19:00.000000000 +0000
@@ -486,25 +486,6 @@
                                                          void *user_data);
 
 /**
- * hb_font_get_glyph_shape_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @draw_funcs: The draw functions to send the shape data to
- * @draw_data: The data accompanying the draw functions
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * Since: 4.0.0
- * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead
- **/
-typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
-                                                hb_codepoint_t glyph,
-                                                hb_draw_funcs_t *draw_funcs, void *draw_data,
-                                                void *user_data);
-
-/**
  * hb_font_draw_glyph_func_t:
  * @font: #hb_font_t to work upon
  * @font_data: @font user data pointer
@@ -804,32 +785,13 @@
                                         void *user_data, hb_destroy_func_t destroy);
 
 /**
- * hb_font_funcs_set_glyph_shape_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_get_glyph_shape_func_t,
- * which is the same as #hb_font_draw_glyph_func_t.
- *
- * Since: 4.0.0
- * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
-                                    hb_font_get_glyph_shape_func_t func,
-                                    void *user_data, hb_destroy_func_t destroy);
-
-/**
  * hb_font_funcs_set_draw_glyph_func:
  * @ffuncs: A font-function structure
  * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
  * @user_data: Data to pass to @func
  * @destroy: (nullable): The function to call when @user_data is not needed anymore
  *
- * Sets the implementation function for #hb_font_draw_glyph_func_t,
- * which is the same as #hb_font_get_glyph_shape_func_t.
+ * Sets the implementation function for #hb_font_draw_glyph_func_t.
  *
  * Since: 7.0.0
  **/
@@ -935,11 +897,6 @@
                              hb_codepoint_t *glyph);
 
 HB_EXTERN void
-hb_font_get_glyph_shape (hb_font_t *font,
-                         hb_codepoint_t glyph,
-                         hb_draw_funcs_t *dfuncs, void *draw_data);
-
-HB_EXTERN void
 hb_font_draw_glyph (hb_font_t *font,
                     hb_codepoint_t glyph,
                     hb_draw_funcs_t *dfuncs, void *draw_data);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ft.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ft.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ft.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ft.cc	2024-01-16 16:19:00.000000000 +0000
@@ -114,7 +114,7 @@
   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
 
   ft_font->cached_serial = (unsigned) -1;
-  ft_font->advance_cache.init ();
+  new (&ft_font->advance_cache) hb_ft_advance_cache_t;
 
   return ft_font;
 }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-iter.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-iter.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-iter.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-iter.hh	2024-01-16 16:19:00.000000000 +0000
@@ -63,6 +63,7 @@
   static constexpr bool is_iterator = true;
   static constexpr bool is_random_access_iterator = false;
   static constexpr bool is_sorted_iterator = false;
+  static constexpr bool has_fast_len = false; // Should be checked in combination with is_random_access_iterator.
 
   private:
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
@@ -393,7 +394,7 @@
 
   private:
   Iter it;
-  hb_reference_wrapper f;
+  mutable hb_reference_wrapper f;
 };
 
 template 
@@ -456,8 +457,8 @@
 
   private:
   Iter it;
-  hb_reference_wrapper p;
-  hb_reference_wrapper f;
+  mutable hb_reference_wrapper p;
+  mutable hb_reference_wrapper f;
 };
 template 
 struct hb_filter_iter_factory_t
@@ -841,7 +842,7 @@
   template 
   auto operator () (Iterable&& it, unsigned count) const HB_AUTO_RETURN
-  ( hb_zip (hb_range (count), it) | hb_map (hb_second) )
+  ( hb_zip (hb_range (count), it) | hb_map_retains_sorting (hb_second) )
 
   /* Specialization arrays. */
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-kern.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-kern.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-kern.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-kern.hh	2024-01-16 16:19:00.000000000 +0000
@@ -53,7 +53,7 @@
       return;
 
     buffer->unsafe_to_concat ();
-    OT::hb_ot_apply_context_t c (1, font, buffer);
+    OT::hb_ot_apply_context_t c (1, font, buffer, hb_blob_get_empty ());
     c.set_lookup_mask (kern_mask);
     c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
     auto &skippy_iter = c.iter_input;
@@ -70,7 +70,7 @@
         continue;
       }
 
-      skippy_iter.reset (idx, 1);
+      skippy_iter.reset (idx);
       unsigned unsafe_to;
       if (!skippy_iter.next (&unsafe_to))
       {
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-limits.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-limits.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-limits.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-limits.hh	2024-01-16 16:19:00.000000000 +0000
@@ -89,6 +89,10 @@
 #endif
 
 
+#ifndef HB_GLYF_VAR_COMPOSITE_MAX_AXES
+#define HB_GLYF_VAR_COMPOSITE_MAX_AXES 4096
+#endif
+
 #ifndef HB_GLYF_MAX_POINTS
 #define HB_GLYF_MAX_POINTS 20000
 #endif
@@ -102,7 +106,7 @@
 #endif
 
 #ifndef HB_COLRV1_MAX_EDGE_COUNT
-#define HB_COLRV1_MAX_EDGE_COUNT 1024
+#define HB_COLRV1_MAX_EDGE_COUNT 65536
 #endif
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh	2024-01-16 16:19:00.000000000 +0000
@@ -180,6 +180,9 @@
                                  hb_lazy_loader_t
                                 >::value Funcs;
 
+  hb_lazy_loader_t () = default;
+  hb_lazy_loader_t (const hb_lazy_loader_t &other) = delete;
+
   void init0 () {} /* Init, when memory is already set to 0. No-op for us. */
   void init ()  { instance.set_relaxed (nullptr); }
   void fini ()  { do_destroy (instance.get_acquire ()); init (); }
@@ -278,7 +281,11 @@
 template 
 struct hb_face_lazy_loader_t : hb_lazy_loader_t,
-                                                hb_face_t, WheresFace> {};
+                                                hb_face_t, WheresFace>
+{
+  // Hack; have them here for API parity with hb_table_lazy_loader_t
+  hb_blob_t *get_blob () { return this->get ()->get_blob (); }
+};
 
 template 
 struct hb_table_lazy_loader_t : hb_lazy_loader_t (face);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-map.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-map.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-map.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-map.cc	2024-01-16 16:19:00.000000000 +0000
@@ -365,7 +365,7 @@
  * @key: (out): Key retrieved
  * @value: (out): Value retrieved
  *
- * Fetches the next key/value paire in @map.
+ * Fetches the next key/value pair in @map.
  *
  * Set @idx to -1 to get started.
  *
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-map.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-map.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-map.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-map.h	2024-01-16 16:19:00.000000000 +0000
@@ -44,7 +44,7 @@
  *
  * Since: 1.7.7
  */
-#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1)
+#define HB_MAP_VALUE_INVALID HB_CODEPOINT_INVALID
 
 /**
  * hb_map_t:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-map.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-map.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-map.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-map.hh	2024-01-16 16:19:00.000000000 +0000
@@ -45,9 +45,9 @@
   hb_hashmap_t ()  { init (); }
   ~hb_hashmap_t () { fini (); }
 
-  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); }
+  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { alloc (o.population); hb_copy (o, *this); }
   hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
-  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { reset (); resize (o.population); hb_copy (o, *this); return *this; }
+  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { reset (); alloc (o.population); hb_copy (o, *this); return *this; }
   hb_hashmap_t& operator= (hb_hashmap_t&& o)  { hb_swap (*this, o); return *this; }
 
   hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t ()
@@ -60,29 +60,32 @@
   hb_hashmap_t (const Iterable &o) : hb_hashmap_t ()
   {
     auto iter = hb_iter (o);
-    if (iter.is_random_access_iterator)
-      resize (hb_len (iter));
+    if (iter.is_random_access_iterator || iter.has_fast_len)
+      alloc (hb_len (iter));
     hb_copy (iter, *this);
   }
 
   struct item_t
   {
     K key;
-    uint32_t hash : 30;
+    uint32_t is_real_ : 1;
     uint32_t is_used_ : 1;
-    uint32_t is_tombstone_ : 1;
+    uint32_t hash : 30;
     V value;
 
     item_t () : key (),
+                is_real_ (false), is_used_ (false),
                 hash (0),
-                is_used_ (false), is_tombstone_ (false),
                 value () {}
 
+    // Needed for https://github.com/harfbuzz/harfbuzz/issues/4138
+    K& get_key () { return key; }
+    V& get_value () { return value; }
+
     bool is_used () const { return is_used_; }
     void set_used (bool is_used) { is_used_ = is_used; }
-    bool is_tombstone () const { return is_tombstone_; }
-    void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
-    bool is_real () const { return is_used_ && !is_tombstone_; }
+    void set_real (bool is_real) { is_real_ = is_real; }
+    bool is_real () const { return is_real_; }
 
     template 
@@ -98,10 +101,15 @@
     bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); }
     bool operator == (const item_t &o) const { return *this == o.key; }
     hb_pair_t get_pair() const { return hb_pair_t (key, value); }
-    hb_pair_t get_pair_ref() const { return hb_pair_t (key, value); }
+    hb_pair_t get_pair_ref() { return hb_pair_t (key, value); }
 
     uint32_t total_hash () const
-    { return (hash * 31) + hb_hash (value); }
+    { return (hash * 31u) + hb_hash (value); }
+
+    static constexpr bool is_trivial = hb_is_trivially_constructible(K) &&
+                                       hb_is_trivially_destructible(K) &&
+                                       hb_is_trivially_constructible(V) &&
+                                       hb_is_trivially_destructible(V);
   };
 
   hb_object_header_t header;
@@ -110,6 +118,7 @@
   unsigned int occupancy; /* Including tombstones. */
   unsigned int mask;
   unsigned int prime;
+  unsigned int max_chain_length;
   item_t *items;
 
   friend void swap (hb_hashmap_t& a, hb_hashmap_t& b)
@@ -123,6 +132,7 @@
     hb_swap (a.occupancy, b.occupancy);
     hb_swap (a.mask, b.mask);
     hb_swap (a.prime, b.prime);
+    hb_swap (a.max_chain_length, b.max_chain_length);
     hb_swap (a.items, b.items);
   }
   void init ()
@@ -133,16 +143,19 @@
     population = occupancy = 0;
     mask = 0;
     prime = 0;
+    max_chain_length = 0;
     items = nullptr;
   }
   void fini ()
   {
     hb_object_fini (this);
 
-    if (likely (items)) {
+    if (likely (items))
+    {
       unsigned size = mask + 1;
-      for (unsigned i = 0; i < size; i++)
-        items[i].~item_t ();
+      if (!item_t::is_trivial)
+        for (unsigned i = 0; i < size; i++)
+          items[i].~item_t ();
       hb_free (items);
       items = nullptr;
     }
@@ -157,7 +170,7 @@
 
   bool in_error () const { return !successful; }
 
-  bool resize (unsigned new_population = 0)
+  bool alloc (unsigned new_population = 0)
   {
     if (unlikely (!successful)) return false;
 
@@ -171,8 +184,11 @@
       successful = false;
       return false;
     }
-    for (auto &_ : hb_iter (new_items, new_size))
-      new (&_) item_t ();
+    if (!item_t::is_trivial)
+      for (auto &_ : hb_iter (new_items, new_size))
+        new (&_) item_t ();
+    else
+      hb_memset (new_items, 0, (size_t) new_size * sizeof (item_t));
 
     unsigned int old_size = size ();
     item_t *old_items = items;
@@ -181,6 +197,7 @@
     population = occupancy = 0;
     mask = new_size - 1;
     prime = prime_for (power);
+    max_chain_length = power * 2;
     items = new_items;
 
     /* Insert back old items. */
@@ -192,7 +209,8 @@
                        old_items[i].hash,
                        std::move (old_items[i].value));
       }
-      old_items[i].~item_t ();
+      if (!item_t::is_trivial)
+        old_items[i].~item_t ();
     }
 
     hb_free (old_items);
@@ -201,72 +219,129 @@
   }
 
   template 
-  bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false)
+  bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool overwrite = true)
   {
     if (unlikely (!successful)) return false;
-    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
-    item_t &item = item_for_hash (key, hash);
+    if (unlikely ((occupancy + occupancy / 2) >= mask && !alloc ())) return false;
+
+    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
+    unsigned int tombstone = (unsigned int) -1;
+    unsigned int i = hash % prime;
+    unsigned length = 0;
+    unsigned step = 0;
+    while (items[i].is_used ())
+    {
+      if ((std::is_integral::value || items[i].hash == hash) &&
+          items[i] == key)
+      {
+        if (!overwrite)
+          return false;
+        else
+          break;
+      }
+      if (!items[i].is_real () && tombstone == (unsigned) -1)
+        tombstone = i;
+      i = (i + ++step) & mask;
+      length++;
+    }
 
-    if (is_delete && !(item == key))
-      return true; /* Trying to delete non-existent key. */
+    item_t &item = items[tombstone == (unsigned) -1 ? i : tombstone];
 
     if (item.is_used ())
     {
       occupancy--;
-      if (!item.is_tombstone ())
-        population--;
+      population -= item.is_real ();
     }
 
     item.key = std::forward (key);
     item.value = std::forward (value);
     item.hash = hash;
     item.set_used (true);
-    item.set_tombstone (is_delete);
+    item.set_real (true);
 
     occupancy++;
-    if (!is_delete)
-      population++;
+    population++;
+
+    if (unlikely (length > max_chain_length) && occupancy * 8 > mask)
+      alloc (mask - 8); // This ensures we jump to next larger size
 
     return true;
   }
 
   template 
-  bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward (value)); }
+  bool set (const K &key, VV&& value, bool overwrite = true) { return set_with_hash (key, hb_hash (key), std::forward (value), overwrite); }
   template 
-  bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward (value)); }
+  bool set (K &&key, VV&& value, bool overwrite = true)
+  {
+    uint32_t hash = hb_hash (key);
+    return set_with_hash (std::move (key), hash, std::forward (value), overwrite);
+  }
+  bool add (const K &key)
+  {
+    uint32_t hash = hb_hash (key);
+    return set_with_hash (key, hash, item_t::default_value ());
+  }
 
   const V& get_with_hash (const K &key, uint32_t hash) const
   {
-    if (unlikely (!items)) return item_t::default_value ();
-    auto &item = item_for_hash (key, hash);
-    return item.is_real () && item == key ? item.value : item_t::default_value ();
+    if (!items) return item_t::default_value ();
+    auto *item = fetch_item (key, hb_hash (key));
+    if (item)
+      return item->value;
+    return item_t::default_value ();
   }
   const V& get (const K &key) const
   {
-    if (unlikely (!items)) return item_t::default_value ();
+    if (!items) return item_t::default_value ();
     return get_with_hash (key, hb_hash (key));
   }
 
-  void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
+  void del (const K &key)
+  {
+    if (!items) return;
+    auto *item = fetch_item (key, hb_hash (key));
+    if (item)
+    {
+      item->set_real (false);
+      population--;
+    }
+  }
 
   /* Has interface. */
   const V& operator [] (K k) const { return get (k); }
   template 
-  bool has (K key, VV **vp = nullptr) const
+  bool has (const K &key, VV **vp = nullptr) const
   {
-    if (unlikely (!items))
-      return false;
-    auto &item = item_for_hash (key, hb_hash (key));
-    if (item.is_real () && item == key)
+    if (!items) return false;
+    auto *item = fetch_item (key, hb_hash (key));
+    if (item)
     {
-      if (vp) *vp = std::addressof (item.value);
+      if (vp) *vp = std::addressof (item->value);
       return true;
     }
-    else
-      return false;
+    return false;
+  }
+  item_t *fetch_item (const K &key, uint32_t hash) const
+  {
+    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
+    unsigned int i = hash % prime;
+    unsigned step = 0;
+    while (items[i].is_used ())
+    {
+      if ((std::is_integral::value || items[i].hash == hash) &&
+          items[i] == key)
+      {
+        if (items[i].is_real ())
+          return &items[i];
+        else
+          return nullptr;
+      }
+      i = (i + ++step) & mask;
+    }
+    return nullptr;
   }
   /* Projection. */
-  V operator () (K k) const { return get (k); }
+  const V& operator () (K k) const { return get (k); }
 
   unsigned size () const { return mask ? mask + 1 : 0; }
 
@@ -323,39 +398,37 @@
 
   auto iter_items () const HB_AUTO_RETURN
   (
-    + hb_iter (items, size ())
+    + hb_iter (items, this->size ())
     | hb_filter (&item_t::is_real)
   )
   auto iter_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_pair_ref)
   )
   auto iter () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_pair)
   )
   auto keys_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::key)
+    + this->iter_items ()
+    | hb_map (&item_t::get_key)
   )
   auto keys () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::key)
+    + this->keys_ref ()
     | hb_map (hb_ridentity)
   )
   auto values_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::value)
+    + this->iter_items ()
+    | hb_map (&item_t::get_value)
   )
   auto values () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::value)
+    + this->values_ref ()
     | hb_map (hb_ridentity)
   )
 
@@ -393,23 +466,6 @@
   hb_hashmap_t& operator << (const hb_pair_t& v)
   { set (std::move (v.first), std::move (v.second)); return *this; }
 
-  item_t& item_for_hash (const K &key, uint32_t hash) const
-  {
-    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
-    unsigned int i = hash % prime;
-    unsigned int step = 0;
-    unsigned int tombstone = (unsigned) -1;
-    while (items[i].is_used ())
-    {
-      if (items[i].hash == hash && items[i] == key)
-        return items[i];
-      if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
-        tombstone = i;
-      i = (i + ++step) & mask;
-    }
-    return items[tombstone == (unsigned) -1 ? i : tombstone];
-  }
-
   static unsigned int prime_for (unsigned int shift)
   {
     /* Following comment and table copied from glib. */
@@ -480,7 +536,7 @@
   hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {}
   hb_map_t& operator= (const hb_map_t&) = default;
   hb_map_t& operator= (hb_map_t&&) = default;
-  hb_map_t (std::initializer_list> lst) : hashmap (lst) {}
+  hb_map_t (std::initializer_list lst) : hashmap (lst) {}
   template 
   hb_map_t (const Iterable &o) : hashmap (o) {}
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-meta.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-meta.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-meta.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-meta.hh	2024-01-16 16:19:00.000000000 +0000
@@ -153,8 +153,8 @@
   hb_reference_wrapper (T v) : v (v) {}
   bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
   bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
-  operator T () const { return v; }
-  T get () const { return v; }
+  operator T& () { return v; }
+  T& get () { return v; }
   T v;
 };
 template 
@@ -163,8 +163,8 @@
   hb_reference_wrapper (T& v) : v (std::addressof (v)) {}
   bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
   bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
-  operator T& () const { return *v; }
-  T& get () const { return *v; }
+  operator T& () { return *v; }
+  T& get () { return *v; }
   T* v;
 };
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh	2024-01-16 16:19:00.000000000 +0000
@@ -38,10 +38,10 @@
 {
   void add (hb_codepoint_t k, hb_codepoint_t v)
   {
-    hb_codepoint_t *i;
-    if (multiples_indices.has (k, &i))
+    hb_vector_t *m;
+    if (multiples.has (k, &m))
     {
-      multiples_values[*i].push (v);
+      m->push (v);
       return;
     }
 
@@ -51,12 +51,7 @@
       hb_codepoint_t old = *old_v;
       singulars.del (k);
 
-      multiples_indices.set (k, multiples_values.length);
-      auto *vec = multiples_values.push ();
-
-      vec->push (old);
-      vec->push (v);
-
+      multiples.set (k, hb_vector_t {old, v});
       return;
     }
 
@@ -69,22 +64,31 @@
     if (singulars.has (k, &v))
       return hb_array (v, 1);
 
-    hb_codepoint_t *i;
-    if (multiples_indices.has (k, &i))
-      return multiples_values[*i].as_array ();
+    hb_vector_t *m;
+    if (multiples.has (k, &m))
+      return m->as_array ();
 
     return hb_array_t ();
   }
 
   bool in_error () const
   {
-    return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error ();
+    if (singulars.in_error () || multiples.in_error ())
+      return true;
+    for (const auto &m : multiples.values_ref ())
+      if (m.in_error ())
+        return true;
+    return false;
+  }
+
+  void alloc (unsigned size)
+  {
+    singulars.alloc (size);
   }
 
   protected:
   hb_map_t singulars;
-  hb_map_t multiples_indices;
-  hb_vector_t> multiples_values;
+  hb_hashmap_t> multiples;
 };
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-null.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-null.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-null.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-null.hh	2024-01-16 16:19:00.000000000 +0000
@@ -37,7 +37,7 @@
 
 /* Global nul-content Null pool.  Enlarge as necessary. */
 
-#define HB_NULL_POOL_SIZE 448
+#define HB_NULL_POOL_SIZE 640
 
 template 
 struct _hb_has_min_size : hb_false_type {};
@@ -85,7 +85,7 @@
 template 
 struct _hb_static_size : hb_integral_constant {};
 template 
-struct _hb_static_size> : hb_integral_constant {};
+struct _hb_static_size> : hb_integral_constant {};
 template 
 using hb_static_size = _hb_static_size;
 #define hb_static_size(T) hb_static_size::value
@@ -176,7 +176,7 @@
 static inline Type& Crap () {
   static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
   Type *obj = reinterpret_cast (_hb_CrapPool);
-  memcpy (obj, &Null (Type), sizeof (*obj));
+  memcpy (obj, std::addressof (Null (Type)), sizeof (*obj));
   return *obj;
 }
 template 
@@ -211,11 +211,11 @@
   T * operator = (T *v_)   { return v = v_; }
   T * operator -> () const { return get (); }
   T & operator * () const  { return *get (); }
-  T ** operator & () const { return &v; }
+  T ** operator & () const { return std::addressof (v); }
   /* Only auto-cast to const types. */
   template  operator const C * () const { return get (); }
   operator const char * () const { return (const char *) get (); }
-  T * get () const { return v ? v : const_cast (&Null (T)); }
+  T * get () const { return v ? v : const_cast (std::addressof (Null (T))); }
   T * get_raw () const { return v; }
 
   private:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh	2024-01-16 16:19:00.000000000 +0000
@@ -31,7 +31,7 @@
 #include "hb.hh"
 
 
-#line 32 "hb-number-parser.hh"
+#line 35 "hb-number-parser.hh"
 static const unsigned char _double_parser_trans_keys[] = {
         0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
         46u, 101u, 0
@@ -135,12 +135,12 @@
 
   int cs;
 
-#line 132 "hb-number-parser.hh"
+#line 139 "hb-number-parser.hh"
         {
         cs = double_parser_start;
         }
 
-#line 135 "hb-number-parser.hh"
+#line 144 "hb-number-parser.hh"
         {
         int _slen;
         int _trans;
@@ -198,7 +198,7 @@
           exp_overflow = true;
 }
         break;
-#line 187 "hb-number-parser.hh"
+#line 202 "hb-number-parser.hh"
         }
 
 _again:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh	2024-01-16 16:19:00.000000000 +0000
@@ -131,7 +131,7 @@
     sfnt_version = sfnt_tag;
     /* Take space for numTables, searchRange, entrySelector, RangeShift
      * and the TableRecords themselves.  */
-    unsigned num_items = it.len ();
+    unsigned num_items = hb_len (it);
     if (unlikely (!tables.serialize (c, num_items))) return_trace (false);
 
     const char *dir_end = (const char *) c->head;
@@ -145,7 +145,7 @@
       unsigned len = blob->length;
 
       /* Allocate room for the table and copy it. */
-      char *start = (char *) c->allocate_size (len);
+      char *start = (char *) c->allocate_size (len, false);
       if (unlikely (!start)) return false;
 
       TableRecord &rec = tables.arrayZ[i];
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh	2024-01-16 16:19:00.000000000 +0000
@@ -312,6 +312,8 @@
 template 
 struct OffsetTo : Offset
 {
+  using target_t = Type;
+
   // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time.
   static_assert (has_null == false ||
                  (hb_has_null_size (Type) || !hb_has_min_size (Type)), "");
@@ -416,12 +418,15 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this))) return_trace (false);
-    if (unlikely (this->is_null ())) return_trace (true);
+    //if (unlikely (this->is_null ())) return_trace (true);
     if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false);
     return_trace (true);
   }
 
   template 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -462,24 +467,16 @@
 
   HB_DELETE_CREATE_COPY_ASSIGN (UnsizedArrayOf);
 
-  const Type& operator [] (int i_) const
+  const Type& operator [] (unsigned int i) const
   {
-    unsigned int i = (unsigned int) i_;
-    const Type *p = &arrayZ[i];
-    if (unlikely ((const void *) p < (const void *) arrayZ)) return Null (Type); /* Overflowed. */
-    _hb_compiler_memory_r_barrier ();
-    return *p;
+    return arrayZ[i];
   }
-  Type& operator [] (int i_)
+  Type& operator [] (unsigned int i)
   {
-    unsigned int i = (unsigned int) i_;
-    Type *p = &arrayZ[i];
-    if (unlikely ((const void *) p < (const void *) arrayZ)) return Crap (Type); /* Overflowed. */
-    _hb_compiler_memory_r_barrier ();
-    return *p;
+    return arrayZ[i];
   }
 
-  unsigned int get_size (unsigned int len) const
+  static unsigned int get_size (unsigned int len)
   { return len * Type::static_size; }
 
   template  operator T * () { return arrayZ; }
@@ -533,6 +530,7 @@
   }
 
   template 
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -721,6 +719,7 @@
   }
 
   template 
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -736,7 +735,7 @@
   bool sanitize_shallow (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (len.sanitize (c) && c->check_array (arrayZ, len));
+    return_trace (len.sanitize (c) && c->check_array_sized (arrayZ, len, sizeof (LenType)));
   }
 
   public:
@@ -797,7 +796,7 @@
 using List16OfOffset16To = List16OfOffsetTo;
 
 /* An array starting at second element. */
-template 
+template 
 struct HeadlessArrayOf
 {
   static constexpr unsigned item_size = Type::static_size;
@@ -861,6 +860,7 @@
   }
 
   template 
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -878,7 +878,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (lenP1.sanitize (c) &&
-                  (!lenP1 || c->check_array (arrayZ, lenP1 - 1)));
+                  (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType))));
   }
 
   public:
@@ -887,6 +887,7 @@
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
+template  using HeadlessArray16Of = HeadlessArrayOf;
 
 /* An array storing length-1. */
 template 
@@ -912,6 +913,7 @@
   { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
 
   template 
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -929,7 +931,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (lenM1.sanitize (c) &&
-                  (c->check_array (arrayZ, lenM1 + 1)));
+                  (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType))));
   }
 
   public:
@@ -1096,6 +1098,7 @@
   { return header.static_size + header.nUnits * header.unitSize; }
 
   template 
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -48,12 +48,24 @@
 
 struct code_pair_t
 {
-  hb_codepoint_t code;
+  unsigned code;
   hb_codepoint_t glyph;
 };
 
+
 using str_buff_t = hb_vector_t;
 using str_buff_vec_t = hb_vector_t;
+using glyph_to_sid_map_t = hb_vector_t;
+
+struct length_f_t
+{
+  template 
+  unsigned operator () (const Iterable &_) const { return hb_len (hb_iter (_)); }
+
+  unsigned operator () (unsigned _) const { return _; }
+}
+HB_FUNCOBJ (length_f);
 
 /* CFF INDEX */
 template 
@@ -62,42 +74,52 @@
   unsigned int offset_array_size () const
   { return offSize * (count + 1); }
 
-  CFFIndex *copy (hb_serialize_context_t *c) const
-  {
-    TRACE_SERIALIZE (this);
-    unsigned int size = get_size ();
-    CFFIndex *out = c->allocate_size (size, false);
-    if (likely (out))
-      hb_memcpy (out, this, size);
-    return_trace (out);
-  }
-
   template 
   bool serialize (hb_serialize_context_t *c,
-                  const Iterable &iterable)
+                  const Iterable &iterable,
+                  const unsigned *p_data_size = nullptr)
   {
     TRACE_SERIALIZE (this);
+    unsigned data_size;
+    if (p_data_size)
+      data_size = *p_data_size;
+    else
+      total_size (iterable, &data_size);
+
     auto it = hb_iter (iterable);
-    serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len));
+    if (unlikely (!serialize_header (c, +it, data_size))) return_trace (false);
+    unsigned char *ret = c->allocate_size (data_size, false);
+    if (unlikely (!ret)) return_trace (false);
     for (const auto &_ : +it)
-      hb_iter (_).copy (c);
+    {
+      unsigned len = _.length;
+      if (!len)
+        continue;
+      if (len <= 1)
+      {
+        *ret++ = *_.arrayZ;
+        continue;
+      }
+      hb_memcpy (ret, _.arrayZ, len);
+      ret += len;
+    }
     return_trace (true);
   }
 
   template 
   bool serialize_header (hb_serialize_context_t *c,
-                        Iterator it)
+                         Iterator it,
+                         unsigned data_size)
   {
     TRACE_SERIALIZE (this);
 
-    unsigned total = + it | hb_reduce (hb_add, 0);
-    unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
+    unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8;
 
     /* serialize CFFIndex header */
     if (unlikely (!c->extend_min (this))) return_trace (false);
-    this->count = it.len ();
+    this->count = hb_len (it);
     if (!this->count) return_trace (true);
     if (unlikely (!c->extend (this->offSize))) return_trace (false);
     this->offSize = off_size;
@@ -106,25 +128,88 @@
 
     /* serialize indices */
     unsigned int offset = 1;
-    unsigned int i = 0;
-    for (unsigned _ : +it)
+    if (HB_OPTIMIZE_SIZE_VAL)
     {
-      set_offset_at (i++, offset);
-      offset += _;
+      unsigned int i = 0;
+      for (const auto &_ : +it)
+      {
+        set_offset_at (i++, offset);
+        offset += length_f (_);
+      }
+      set_offset_at (i, offset);
     }
-    set_offset_at (i, offset);
+    else
+      switch (off_size)
+      {
+        case 1:
+        {
+          HBUINT8 *p = (HBUINT8 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        case 2:
+        {
+          HBUINT16 *p = (HBUINT16 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        case 3:
+        {
+          HBUINT24 *p = (HBUINT24 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        case 4:
+        {
+          HBUINT32 *p = (HBUINT32 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        default:
+        break;
+      }
 
+    assert (offset == data_size + 1);
     return_trace (true);
   }
 
   template 
-  static unsigned total_size (const Iterable &iterable)
+  static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr)
   {
-    auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len);
-    if (!it) return 0;
+    auto it = + hb_iter (iterable);
+    if (!it)
+    {
+      if (data_size) *data_size = 0;
+      return min_size;
+    }
+
+    unsigned total = 0;
+    for (const auto &_ : +it)
+      total += length_f (_);
+
+    if (data_size) *data_size = total;
 
-    unsigned total = + it | hb_reduce (hb_add, 0);
     unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
 
     return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total;
@@ -133,13 +218,16 @@
   void set_offset_at (unsigned int index, unsigned int offset)
   {
     assert (index <= count);
-    HBUINT8 *p = offsets + offSize * index + offSize;
+
     unsigned int size = offSize;
-    for (; size; size--)
+    const HBUINT8 *p = offsets;
+    switch (size)
     {
-      --p;
-      *p = offset & 0xFF;
-      offset >>= 8;
+      case 1: ((HBUINT8  *) p)[index] = offset; break;
+      case 2: ((HBUINT16 *) p)[index] = offset; break;
+      case 3: ((HBUINT24 *) p)[index] = offset; break;
+      case 4: ((HBUINT32 *) p)[index] = offset; break;
+      default: return;
     }
   }
 
@@ -149,37 +237,30 @@
     assert (index <= count);
 
     unsigned int size = offSize;
-    const HBUINT8 *p = offsets + size * index;
+    const HBUINT8 *p = offsets;
     switch (size)
     {
-      case 1: return * (HBUINT8  *) p;
-      case 2: return * (HBUINT16 *) p;
-      case 3: return * (HBUINT24 *) p;
-      case 4: return * (HBUINT32 *) p;
+      case 1: return ((HBUINT8  *) p)[index];
+      case 2: return ((HBUINT16 *) p)[index];
+      case 3: return ((HBUINT24 *) p)[index];
+      case 4: return ((HBUINT32 *) p)[index];
       default: return 0;
     }
   }
 
-  unsigned int length_at (unsigned int index) const
-  {
-    unsigned offset0 = offset_at (index);
-    unsigned offset1 = offset_at (index + 1);
-    if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
-      return 0;
-    return offset1 - offset0;
-  }
-
   const unsigned char *data_base () const
-  { return (const unsigned char *) this + min_size + offSize.static_size + offset_array_size (); }
+  { return (const unsigned char *) this + min_size + offSize.static_size - 1 + offset_array_size (); }
   public:
 
   hb_ubytes_t operator [] (unsigned int index) const
   {
     if (unlikely (index >= count)) return hb_ubytes_t ();
     _hb_compiler_memory_r_barrier ();
-    unsigned length = length_at (index);
-    if (unlikely (!length)) return hb_ubytes_t ();
-    return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
+    unsigned offset0 = offset_at (index);
+    unsigned offset1 = offset_at (index + 1);
+    if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
+      return hb_ubytes_t ();
+    return hb_ubytes_t (data_base () + offset0, offset1 - offset0);
   }
 
   unsigned int get_size () const
@@ -197,7 +278,7 @@
                            (count < count + 1u &&
                             c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 &&
                             c->check_array (offsets, offSize, count + 1u) &&
-                            c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count) - 1)))));
+                            c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count))))));
   }
 
   public:
@@ -211,47 +292,6 @@
   DEFINE_SIZE_MIN (COUNT::static_size);
 };
 
-template 
-struct CFFIndexOf : CFFIndex
-{
-  template 
-  bool serialize (hb_serialize_context_t *c,
-                  unsigned int offSize_,
-                  const DATA *dataArray,
-                  unsigned int dataArrayLen,
-                  const hb_vector_t &dataSizeArray,
-                  const PARAM1 ¶m1,
-                  const PARAM2 ¶m2)
-  {
-    TRACE_SERIALIZE (this);
-    /* serialize CFFIndex header */
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    this->count = dataArrayLen;
-    this->offSize = offSize_;
-    if (unlikely (!c->allocate_size (offSize_ * (dataArrayLen + 1), false)))
-      return_trace (false);
-
-    /* serialize indices */
-    unsigned int  offset = 1;
-    unsigned int  i = 0;
-    for (; i < dataArrayLen; i++)
-    {
-      this->set_offset_at (i, offset);
-      offset += dataSizeArray[i];
-    }
-    this->set_offset_at (i, offset);
-
-    /* serialize data */
-    for (unsigned int i = 0; i < dataArrayLen; i++)
-    {
-      TYPE *dest = c->start_embed ();
-      if (unlikely (!dest || !dest->serialize (c, dataArray[i], param1, param2)))
-        return_trace (false);
-    }
-    return_trace (true);
-  }
-};
-
 /* Top Dict, Font Dict, Private Dict */
 struct Dict : UnsizedByteStr
 {
@@ -327,7 +367,7 @@
 };
 
 template 
-struct FDArray : CFFIndexOf
+struct FDArray : CFFIndex
 {
   template 
   bool serialize (hb_serialize_context_t *c,
@@ -338,7 +378,11 @@
 
     /* serialize INDEX data */
     hb_vector_t sizes;
+    if (it.is_random_access_iterator)
+      sizes.alloc (hb_len (it));
+
     c->push ();
+    char *data_base = c->head;
     + it
     | hb_map ([&] (const hb_pair_t &_)
     {
@@ -348,10 +392,16 @@
               })
     | hb_sink (sizes)
     ;
+    unsigned data_size = c->head - data_base;
     c->pop_pack (false);
 
+    if (unlikely (sizes.in_error ())) return_trace (false);
+
+    /* It just happens that the above is packed right after the header below.
+     * Such a hack. */
+
     /* serialize INDEX header */
-    return_trace (CFFIndex::serialize_header (c, hb_iter (sizes)));
+    return_trace (CFFIndex::serialize_header (c, hb_iter (sizes), data_size));
   }
 };
 
@@ -368,8 +418,11 @@
     return_trace (true);
   }
 
-  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
-  { return (hb_codepoint_t) fds[glyph]; }
+  unsigned get_fd (hb_codepoint_t glyph) const
+  { return fds[glyph]; }
+
+  hb_pair_t get_fd_range (hb_codepoint_t glyph) const
+  { return {fds[glyph], glyph + 1}; }
 
   unsigned int get_size (unsigned int num_glyphs) const
   { return HBUINT8::static_size * num_glyphs; }
@@ -427,12 +480,20 @@
     return +1;
   }
 
-  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
+  unsigned get_fd (hb_codepoint_t glyph) const
   {
     auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
     return range ? range->fd : ranges[nRanges () - 1].fd;
   }
 
+  hb_pair_t get_fd_range (hb_codepoint_t glyph) const
+  {
+    auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
+    unsigned fd = range ? range->fd : ranges[nRanges () - 1].fd;
+    hb_codepoint_t end = range ? range[1].first : ranges[nRanges () - 1].first;
+    return {fd, end};
+  }
+
   GID_TYPE        &nRanges ()       { return ranges.len; }
   GID_TYPE         nRanges () const { return ranges.len; }
   GID_TYPE       &sentinel ()       { return StructAfter (ranges[nRanges () - 1]); }
@@ -469,7 +530,7 @@
     }
   }
 
-  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
+  unsigned get_fd (hb_codepoint_t glyph) const
   {
     if (this == &Null (FDSelect)) return 0;
 
@@ -480,6 +541,18 @@
     default:return 0;
     }
   }
+  /* Returns pair of fd and one after last glyph in range. */
+  hb_pair_t get_fd_range (hb_codepoint_t glyph) const
+  {
+    if (this == &Null (FDSelect)) return {0, 1};
+
+    switch (format)
+    {
+    case 0: return u.format0.get_fd_range (glyph);
+    case 3: return u.format3.get_fd_range (glyph);
+    default:return {0, 1};
+    }
+  }
 
   bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
   {
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc	2024-01-16 16:19:00.000000000 +0000
@@ -574,11 +574,11 @@
 
 struct get_seac_param_t
 {
-  get_seac_param_t (const OT::cff1::accelerator_t *_cff) : cff (_cff) {}
+  get_seac_param_t (const OT::cff1::accelerator_subset_t *_cff) : cff (_cff) {}
 
   bool has_seac () const { return base && accent; }
 
-  const OT::cff1::accelerator_t *cff;
+  const OT::cff1::accelerator_subset_t *cff;
   hb_codepoint_t  base = 0;
   hb_codepoint_t  accent = 0;
 };
@@ -596,7 +596,7 @@
   }
 };
 
-bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const
+bool OT::cff1::accelerator_subset_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const
 {
   if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -28,7 +28,7 @@
 #define HB_OT_CFF1_TABLE_HH
 
 #include "hb-ot-cff-common.hh"
-#include "hb-subset-cff1.hh"
+#include "hb-subset-cff-common.hh"
 #include "hb-draw.hh"
 #include "hb-paint.hh"
 
@@ -44,7 +44,7 @@
  * CFF -- Compact Font Format (CFF)
  * https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
  */
-#define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ')
+#define HB_OT_TAG_CFF1 HB_TAG('C','F','F',' ')
 
 #define CFF_UNDEF_SID   CFF_UNDEF_CODE
 
@@ -52,7 +52,6 @@
 enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 };
 
 typedef CFFIndex  CFF1Index;
-template  struct CFF1IndexOf : CFFIndexOf {};
 
 typedef CFFIndex CFF1Index;
 typedef CFF1Index          CFF1CharStrings;
@@ -110,6 +109,7 @@
 
   hb_codepoint_t get_code (hb_codepoint_t glyph) const
   {
+    /* TODO: Add cache like get_sid. */
     assert (glyph > 0);
     glyph--;
     for (unsigned int i = 0; i < nRanges (); i++)
@@ -173,11 +173,7 @@
   bool serialize (hb_serialize_context_t *c, const Encoding &src)
   {
     TRACE_SERIALIZE (this);
-    unsigned int size = src.get_size ();
-    Encoding *dest = c->allocate_size (size);
-    if (unlikely (!dest)) return_trace (false);
-    hb_memcpy (dest, &src, size);
-    return_trace (true);
+    return_trace (c->embed (src));
   }
 
   /* serialize a subset Encoding */
@@ -312,26 +308,29 @@
 };
 
 /* Charset */
-struct Charset0 {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
+struct Charset0
+{
+  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && sids[num_glyphs - 1].sanitize (c));
+    if (num_charset_entries) *num_charset_entries = num_glyphs;
+    return_trace (sids.sanitize (c, num_glyphs - 1));
   }
 
   hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const
   {
     if (unlikely (glyph >= num_glyphs)) return 0;
-    if (glyph == 0)
+    if (unlikely (glyph == 0))
       return 0;
     else
       return sids[glyph - 1];
   }
 
-  void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
+  void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const
   {
+    mapping->resize (num_glyphs, false);
     for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++)
-      mapping->set (gid, sids[gid - 1]);
+      mapping->arrayZ[gid] = {sids[gid - 1], gid};
   }
 
   hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
@@ -347,13 +346,13 @@
     return 0;
   }
 
-  unsigned int get_size (unsigned int num_glyphs) const
+  static unsigned int get_size (unsigned int num_glyphs)
   {
     assert (num_glyphs > 0);
-    return HBUINT16::static_size * (num_glyphs - 1);
+    return UnsizedArrayOf::get_size (num_glyphs - 1);
   }
 
-  HBUINT16  sids[HB_VAR_ARRAY];
+  UnsizedArrayOf sids;
 
   DEFINE_SIZE_ARRAY(0, sids);
 };
@@ -374,38 +373,62 @@
 
 template 
 struct Charset1_2 {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
+  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this)))
       return_trace (false);
     num_glyphs--;
-    for (unsigned int i = 0; num_glyphs > 0; i++)
+    unsigned i;
+    for (i = 0; num_glyphs > 0; i++)
     {
       if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1)))
         return_trace (false);
       num_glyphs -= (ranges[i].nLeft + 1);
     }
+    if (num_charset_entries)
+      *num_charset_entries = i;
     return_trace (true);
   }
 
-  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const
+  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs,
+                          code_pair_t *cache = nullptr) const
   {
     if (unlikely (glyph >= num_glyphs)) return 0;
-    if (glyph == 0) return 0;
-    glyph--;
-    for (unsigned int i = 0;; i++)
+    unsigned i;
+    hb_codepoint_t start_glyph;
+    if (cache && likely (cache->glyph <= glyph))
     {
-      if (glyph <= ranges[i].nLeft)
-        return (hb_codepoint_t) ranges[i].first + glyph;
-      glyph -= (ranges[i].nLeft + 1);
+      i = cache->code;
+      start_glyph = cache->glyph;
+    }
+    else
+    {
+      if (unlikely (glyph == 0)) return 0;
+      i = 0;
+      start_glyph = 1;
+    }
+    glyph -= start_glyph;
+    for (;; i++)
+    {
+      unsigned count = ranges[i].nLeft;
+      if (glyph <= count)
+      {
+        if (cache)
+          *cache = {i, start_glyph};
+        return ranges[i].first + glyph;
+      }
+      count++;
+      start_glyph += count;
+      glyph -= count;
     }
 
     return 0;
   }
 
-  void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
+  void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const
   {
+    mapping->resize (num_glyphs, false);
     hb_codepoint_t gid = 1;
     if (gid >= num_glyphs)
       return;
@@ -413,8 +436,9 @@
     {
       hb_codepoint_t sid = ranges[i].first;
       unsigned count = ranges[i].nLeft + 1;
+      unsigned last = gid + count;
       for (unsigned j = 0; j < count; j++)
-        mapping->set (gid++, sid++);
+        mapping->arrayZ[gid++] = {sid++, last - 1};
 
       if (gid >= num_glyphs)
         break;
@@ -439,21 +463,26 @@
 
   unsigned int get_size (unsigned int num_glyphs) const
   {
-    unsigned int size = HBUINT8::static_size;
-    int glyph = (int)num_glyphs;
+    int glyph = (int) num_glyphs;
+    unsigned num_ranges = 0;
 
     assert (glyph > 0);
     glyph--;
     for (unsigned int i = 0; glyph > 0; i++)
     {
       glyph -= (ranges[i].nLeft + 1);
-      size += Charset_Range::static_size;
+      num_ranges++;
     }
 
-    return size;
+    return get_size_for_ranges (num_ranges);
+  }
+
+  static unsigned int get_size_for_ranges (unsigned int num_ranges)
+  {
+    return UnsizedArrayOf >::get_size (num_ranges);
   }
 
-  Charset_Range   ranges[HB_VAR_ARRAY];
+  UnsizedArrayOf> ranges;
 
   DEFINE_SIZE_ARRAY (0, ranges);
 };
@@ -469,11 +498,7 @@
   bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
-    unsigned int size = src.get_size (num_glyphs);
-    Charset *dest = c->allocate_size (size);
-    if (unlikely (!dest)) return_trace (false);
-    hb_memcpy (dest, &src, size);
-    return_trace (true);
+    return_trace (c->embed ((const char *) &src, src.get_size (num_glyphs)));
   }
 
   /* serialize a subset Charset */
@@ -490,13 +515,13 @@
     {
     case 0:
     {
-      Charset0 *fmt0 = c->allocate_size (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
+      Charset0 *fmt0 = c->allocate_size (Charset0::get_size (num_glyphs), false);
       if (unlikely (!fmt0)) return_trace (false);
       unsigned int glyph = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-        hb_codepoint_t sid = sid_ranges[i].code;
-        for (int left = (int)sid_ranges[i].glyph; left >= 0; left--)
+        hb_codepoint_t sid = sid_ranges.arrayZ[i].code;
+        for (int left = (int)sid_ranges.arrayZ[i].glyph; left >= 0; left--)
           fmt0->sids[glyph++] = sid++;
       }
     }
@@ -504,29 +529,35 @@
 
     case 1:
     {
-      Charset1 *fmt1 = c->allocate_size (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
+      Charset1 *fmt1 = c->allocate_size (Charset1::get_size_for_ranges (sid_ranges.length), false);
       if (unlikely (!fmt1)) return_trace (false);
+      hb_codepoint_t all_glyphs = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-        if (unlikely (!(sid_ranges[i].glyph <= 0xFF)))
-          return_trace (false);
-        fmt1->ranges[i].first = sid_ranges[i].code;
-        fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
+        auto &_ = sid_ranges.arrayZ[i];
+        all_glyphs |= _.glyph;
+        fmt1->ranges[i].first = _.code;
+        fmt1->ranges[i].nLeft = _.glyph;
       }
+      if (unlikely (!(all_glyphs <= 0xFF)))
+        return_trace (false);
     }
     break;
 
     case 2:
     {
-      Charset2 *fmt2 = c->allocate_size (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
+      Charset2 *fmt2 = c->allocate_size (Charset2::get_size_for_ranges (sid_ranges.length), false);
       if (unlikely (!fmt2)) return_trace (false);
+      hb_codepoint_t all_glyphs = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-        if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF)))
-          return_trace (false);
-        fmt2->ranges[i].first = sid_ranges[i].code;
-        fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
+        auto &_ = sid_ranges.arrayZ[i];
+        all_glyphs |= _.glyph;
+        fmt2->ranges[i].first = _.code;
+        fmt2->ranges[i].nLeft = _.glyph;
       }
+      if (unlikely (!(all_glyphs <= 0xFFFF)))
+        return_trace (false);
     }
     break;
 
@@ -545,18 +576,19 @@
     }
   }
 
-  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs) const
+  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs,
+                          code_pair_t *cache = nullptr) const
   {
     switch (format)
     {
     case 0: return u.format0.get_sid (glyph, num_glyphs);
-    case 1: return u.format1.get_sid (glyph, num_glyphs);
-    case 2: return u.format2.get_sid (glyph, num_glyphs);
+    case 1: return u.format1.get_sid (glyph, num_glyphs, cache);
+    case 2: return u.format2.get_sid (glyph, num_glyphs, cache);
     default:return 0;
     }
   }
 
-  void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
+  void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const
   {
     switch (format)
     {
@@ -578,7 +610,7 @@
     }
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  bool sanitize (hb_sanitize_context_t *c, unsigned *num_charset_entries) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this)))
@@ -586,9 +618,9 @@
 
     switch (format)
     {
-    case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
-    case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
-    case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
+    case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries));
+    case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries));
+    case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries));
     default:return_trace (false);
     }
   }
@@ -606,10 +638,10 @@
 struct CFF1StringIndex : CFF1Index
 {
   bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
-                  const hb_inc_bimap_t &sidmap)
+                  const hb_vector_t &sidmap)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
+    if (unlikely ((strings.count == 0) || (sidmap.length == 0)))
     {
       if (unlikely (!c->extend_min (this->count)))
         return_trace (false);
@@ -617,15 +649,13 @@
       return_trace (true);
     }
 
-    byte_str_array_t bytesArray;
-    if (!bytesArray.resize (sidmap.get_population ()))
-      return_trace (false);
-    for (unsigned int i = 0; i < strings.count; i++)
-    {
-      hb_codepoint_t  j = sidmap[i];
-      if (j != HB_MAP_VALUE_INVALID)
-        bytesArray[j] = strings[i];
-    }
+    if (unlikely (sidmap.in_error ())) return_trace (false);
+
+    // Save this in a vector since serialize() iterates it twice.
+    hb_vector_t bytesArray (+ hb_iter (sidmap)
+                                         | hb_map (strings));
+
+    if (unlikely (bytesArray.in_error ())) return_trace (false);
 
     bool result = CFF1Index::serialize (c, bytesArray);
     return_trace (result);
@@ -932,7 +962,7 @@
   }
 };
 
-struct cff1_private_dict_opset_subset : dict_opset_t
+struct cff1_private_dict_opset_subset_t : dict_opset_t
 {
   static void process_op (op_code_t op, num_interp_env_t& env, cff1_private_dict_values_subset_t& dictval)
   {
@@ -978,7 +1008,7 @@
 typedef dict_interpreter_t cff1_font_dict_interpreter_t;
 
 typedef CFF1Index CFF1NameIndex;
-typedef CFF1IndexOf CFF1TopDictIndex;
+typedef CFF1Index CFF1TopDictIndex;
 
 struct cff1_font_dict_values_mod_t
 {
@@ -1019,7 +1049,7 @@
 
 struct cff1
 {
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_cff1;
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF1;
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -1031,8 +1061,12 @@
   template 
   struct accelerator_templ_t
   {
-    void init (hb_face_t *face)
+    static constexpr hb_tag_t tableTag = cff1::tableTag;
+
+    accelerator_templ_t (hb_face_t *face)
     {
+      if (!face) return;
+
       topDict.init ();
       fontDicts.init ();
       privateDicts.init ();
@@ -1046,22 +1080,22 @@
       const OT::cff1 *cff = this->blob->template as ();
 
       if (cff == &Null (OT::cff1))
-      { fini (); return; }
+        goto fail;
 
       nameIndex = &cff->nameIndex (cff);
       if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc))
-      { fini (); return; }
+        goto fail;
 
       topDictIndex = &StructAtOffset (nameIndex, nameIndex->get_size ());
       if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0))
-      { fini (); return; }
+        goto fail;
 
       { /* parse top dict */
         const hb_ubytes_t topDictStr = (*topDictIndex)[0];
-        if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
+        if (unlikely (!topDictStr.sanitize (&sc)))   goto fail;
         cff1_top_dict_interp_env_t env (topDictStr);
         cff1_top_dict_interpreter_t top_interp (env);
-        if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
+        if (unlikely (!top_interp.interpret (topDict)))   goto fail;
       }
 
       if (is_predef_charset ())
@@ -1069,7 +1103,7 @@
       else
       {
         charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset);
-        if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc))) { fini (); return; }
+        if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries)))   goto fail;
       }
 
       fdCount = 1;
@@ -1079,7 +1113,7 @@
         fdSelect = &StructAtOffsetOrNull (cff, topDict.FDSelectOffset);
         if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) ||
             (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count)))
-        { fini (); return; }
+          goto fail;
 
         fdCount = fdArray->count;
       }
@@ -1092,36 +1126,36 @@
       encoding = &Null (Encoding);
       if (is_CID ())
       {
-        if (unlikely (charset == &Null (Charset))) { fini (); return; }
+        if (unlikely (charset == &Null (Charset)))   goto fail;
       }
       else
       {
         if (!is_predef_encoding ())
         {
           encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset);
-          if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
+          if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc)))   goto fail;
         }
       }
 
       stringIndex = &StructAtOffset (topDictIndex, topDictIndex->get_size ());
       if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc))
-      { fini (); return; }
+        goto fail;
 
       globalSubrs = &StructAtOffset (stringIndex, stringIndex->get_size ());
       if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc))
-      { fini (); return; }
+        goto fail;
 
       charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset);
 
       if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc)))
-      { fini (); return; }
+        goto fail;
 
       num_glyphs = charStrings->count;
       if (num_glyphs != sc.get_num_glyphs ())
-      { fini (); return; }
+        goto fail;
 
       if (unlikely (!privateDicts.resize (fdCount)))
-      { fini (); return; }
+        goto fail;
       for (unsigned int i = 0; i < fdCount; i++)
         privateDicts[i].init ();
 
@@ -1131,27 +1165,27 @@
         for (unsigned int i = 0; i < fdCount; i++)
         {
           hb_ubytes_t fontDictStr = (*fdArray)[i];
-          if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
+          if (unlikely (!fontDictStr.sanitize (&sc)))   goto fail;
           cff1_font_dict_values_t *font;
           cff1_top_dict_interp_env_t env (fontDictStr);
           cff1_font_dict_interpreter_t font_interp (env);
           font = fontDicts.push ();
-          if (unlikely (fontDicts.in_error ())) { fini (); return; }
+          if (unlikely (fontDicts.in_error ()))   goto fail;
 
           font->init ();
-          if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
+          if (unlikely (!font_interp.interpret (*font)))   goto fail;
           PRIVDICTVAL *priv = &privateDicts[i];
           const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
-          if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
+          if (unlikely (!privDictStr.sanitize (&sc)))   goto fail;
           num_interp_env_t env2 (privDictStr);
           dict_interpreter_t priv_interp (env2);
           priv->init ();
-          if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
+          if (unlikely (!priv_interp.interpret (*priv)))   goto fail;
 
           priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset);
           if (priv->localSubrs != &Null (CFF1Subrs) &&
               unlikely (!priv->localSubrs->sanitize (&sc)))
-          { fini (); return; }
+            goto fail;
         }
       }
       else  /* non-CID */
@@ -1160,20 +1194,25 @@
         PRIVDICTVAL *priv = &privateDicts[0];
 
         const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
-        if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
+        if (unlikely (!privDictStr.sanitize (&sc)))   goto fail;
         num_interp_env_t env (privDictStr);
         dict_interpreter_t priv_interp (env);
         priv->init ();
-        if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
+        if (unlikely (!priv_interp.interpret (*priv)))   goto fail;
 
         priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset);
         if (priv->localSubrs != &Null (CFF1Subrs) &&
             unlikely (!priv->localSubrs->sanitize (&sc)))
-        { fini (); return; }
+          goto fail;
       }
-    }
 
-    void fini ()
+      return;
+
+      fail:
+        _fini ();
+    }
+    ~accelerator_templ_t () { _fini (); }
+    void _fini ()
     {
       sc.end_processing ();
       topDict.fini ();
@@ -1183,6 +1222,8 @@
       blob = nullptr;
     }
 
+    hb_blob_t *get_blob () const { return blob; }
+
     bool is_valid () const { return blob; }
     bool   is_CID () const { return topDict.is_CID (); }
 
@@ -1203,13 +1244,14 @@
 
     bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
 
-    hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
+    hb_codepoint_t glyph_to_code (hb_codepoint_t glyph,
+                                  code_pair_t *glyph_to_sid_cache = nullptr) const
     {
       if (encoding != &Null (Encoding))
         return encoding->get_code (glyph);
       else
       {
-        hb_codepoint_t sid = glyph_to_sid (glyph);
+        hb_codepoint_t sid = glyph_to_sid (glyph, glyph_to_sid_cache);
         if (sid == 0) return 0;
         hb_codepoint_t code = 0;
         switch (topDict.EncodingOffset)
@@ -1227,12 +1269,14 @@
       }
     }
 
-    hb_map_t *create_glyph_to_sid_map () const
+    glyph_to_sid_map_t *create_glyph_to_sid_map () const
     {
       if (charset != &Null (Charset))
       {
-        hb_map_t *mapping = hb_map_create ();
-        mapping->set (0, 0);
+        auto *mapping = (glyph_to_sid_map_t *) hb_malloc (sizeof (glyph_to_sid_map_t));
+        if (unlikely (!mapping)) return nullptr;
+        mapping = new (mapping) glyph_to_sid_map_t ();
+        mapping->push (code_pair_t {0, 1});
         charset->collect_glyph_to_sid_map (mapping, num_glyphs);
         return mapping;
       }
@@ -1240,10 +1284,11 @@
         return nullptr;
     }
 
-    hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const
+    hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph,
+                                 code_pair_t *cache = nullptr) const
     {
       if (charset != &Null (Charset))
-        return charset->get_sid (glyph, num_glyphs);
+        return charset->get_sid (glyph, num_glyphs, cache);
       else
       {
         hb_codepoint_t sid = 0;
@@ -1312,19 +1357,17 @@
     hb_vector_t privateDicts;
 
     unsigned int             num_glyphs = 0;
+    unsigned int             num_charset_entries = 0;
   };
 
   struct accelerator_t : accelerator_templ_t
   {
-    accelerator_t (hb_face_t *face)
+    accelerator_t (hb_face_t *face) : SUPER (face)
     {
-      SUPER::init (face);
-
       glyph_names.set_relaxed (nullptr);
 
       if (!is_valid ()) return;
       if (is_CID ()) return;
-
     }
     ~accelerator_t ()
     {
@@ -1334,8 +1377,6 @@
         names->fini ();
         hb_free (names);
       }
-
-      SUPER::fini ();
     }
 
     bool get_glyph_name (hb_codepoint_t glyph,
@@ -1386,9 +1427,10 @@
           /* TODO */
 
           /* fill glyph names */
+          code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
           for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
           {
-            hb_codepoint_t      sid = glyph_to_sid (gid);
+            hb_codepoint_t      sid = glyph_to_sid (gid, &glyph_to_sid_cache);
             gname_t     gname;
             gname.sid = sid;
             if (sid < cff1_std_strings_length)
@@ -1426,7 +1468,6 @@
 
     HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
     HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const;
-    HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
     HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
 
     private:
@@ -1453,9 +1494,24 @@
     typedef accelerator_templ_t SUPER;
   };
 
-  struct accelerator_subset_t : accelerator_templ_t {};
+  struct accelerator_subset_t : accelerator_templ_t
+  {
+    accelerator_subset_t (hb_face_t *face) : SUPER (face) {}
+    ~accelerator_subset_t ()
+    {
+      if (cff_accelerator)
+        cff_subset_accelerator_t::destroy (cff_accelerator);
+    }
+
+    HB_INTERNAL bool subset (hb_subset_context_t *c) const;
+    HB_INTERNAL bool serialize (hb_serialize_context_t *c,
+                                struct cff1_subset_plan &plan) const;
+    HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
+
+    mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr;
 
-  bool subset (hb_subset_context_t *c) const { return hb_subset_cff1 (c); }
+    typedef accelerator_templ_t SUPER;
+  };
 
   protected:
   HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_code (hb_codepoint_t sid);
@@ -1479,6 +1535,10 @@
   cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {}
 };
 
+struct cff1_subset_accelerator_t : cff1::accelerator_subset_t {
+  cff1_subset_accelerator_t (hb_face_t *face) : cff1::accelerator_subset_t (face) {}
+};
+
 } /* namespace OT */
 
 #endif /* HB_OT_CFF1_TABLE_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -28,7 +28,7 @@
 #define HB_OT_CFF2_TABLE_HH
 
 #include "hb-ot-cff-common.hh"
-#include "hb-subset-cff2.hh"
+#include "hb-subset-cff-common.hh"
 #include "hb-draw.hh"
 #include "hb-paint.hh"
 
@@ -38,10 +38,9 @@
  * CFF2 -- Compact Font Format (CFF) Version 2
  * https://docs.microsoft.com/en-us/typography/opentype/spec/cff2
  */
-#define HB_OT_TAG_cff2 HB_TAG('C','F','F','2')
+#define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2')
 
 typedef CFFIndex  CFF2Index;
-template  struct CFF2IndexOf : CFFIndexOf {};
 
 typedef CFF2Index         CFF2CharStrings;
 typedef Subrs   CFF2Subrs;
@@ -379,7 +378,7 @@
 
 struct cff2
 {
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_cff2;
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF2;
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -391,8 +390,12 @@
   template 
   struct accelerator_templ_t
   {
+    static constexpr hb_tag_t tableTag = cff2::tableTag;
+
     accelerator_templ_t (hb_face_t *face)
     {
+      if (!face) return;
+
       topDict.init ();
       fontDicts.init ();
       privateDicts.init ();
@@ -464,7 +467,6 @@
           goto fail;
       }
 
-
       return;
 
       fail:
@@ -481,11 +483,13 @@
       blob = nullptr;
     }
 
-    hb_map_t *create_glyph_to_sid_map () const
+    hb_vector_t *create_glyph_to_sid_map () const
     {
       return nullptr;
     }
 
+    hb_blob_t *get_blob () const { return blob; }
+
     bool is_valid () const { return blob; }
 
     protected:
@@ -518,9 +522,24 @@
     HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
   };
 
-  typedef accelerator_templ_t accelerator_subset_t;
+  struct accelerator_subset_t : accelerator_templ_t
+  {
+    accelerator_subset_t (hb_face_t *face) : SUPER (face) {}
+    ~accelerator_subset_t ()
+    {
+      if (cff_accelerator)
+        cff_subset_accelerator_t::destroy (cff_accelerator);
+    }
+
+    HB_INTERNAL bool subset (hb_subset_context_t *c) const;
+    HB_INTERNAL bool serialize (hb_serialize_context_t *c,
+                                struct cff2_subset_plan &plan,
+                                hb_array_t normalized_coords) const;
+
+    mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr;
 
-  bool subset (hb_subset_context_t *c) const { return hb_subset_cff2 (c); }
+    typedef accelerator_templ_t SUPER;
+  };
 
   public:
   FixedVersion         version;        /* Version of CFF2 table. set to 0x0200u */
@@ -535,6 +554,10 @@
   cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {}
 };
 
+struct cff2_subset_accelerator_t : cff2::accelerator_subset_t {
+  cff2_subset_accelerator_t (hb_face_t *face) : cff2::accelerator_subset_t (face) {}
+};
+
 } /* namespace OT */
 
 #endif /* HB_OT_CFF2_TABLE_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -277,10 +277,10 @@
       }
     } writer(c);
 
-    writer.end_code_ = c->allocate_size (HBUINT16::static_size * segcount);
-    c->allocate_size (2); // padding
-    writer.start_code_ = c->allocate_size (HBUINT16::static_size * segcount);
-    writer.id_delta_ = c->allocate_size (HBINT16::static_size * segcount);
+    writer.end_code_ = c->allocate_size (HBUINT16::static_size * segcount, false);
+    (void) c->allocate_size (2); // padding
+    writer.start_code_ = c->allocate_size (HBUINT16::static_size * segcount, false);
+    writer.id_delta_ = c->allocate_size (HBINT16::static_size * segcount, false);
 
     if (unlikely (!writer.end_code_ || !writer.start_code_ || !writer.id_delta_)) return false;
 
@@ -325,7 +325,7 @@
   {
     auto format4_iter =
     + it
-    | hb_filter ([&] (const hb_pair_t _)
+    | hb_filter ([&] (const hb_codepoint_pair_t _)
                  { return _.first <= 0xFFFF; })
     ;
 
@@ -335,7 +335,7 @@
     if (unlikely (!c->extend_min (this))) return;
     this->format = 4;
 
-    hb_vector_t> cp_to_gid {
+    hb_vector_t cp_to_gid {
       format4_iter
     };
 
@@ -757,8 +757,7 @@
       hb_codepoint_t gid = this->groups[i].glyphID;
       if (!gid)
       {
-        /* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */
-        if (! T::group_get_glyph (this->groups[i], end)) continue;
+        if (T::formatNumber == 13) continue;
         start++;
         gid++;
       }
@@ -766,11 +765,13 @@
       if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs))
         end = start + (hb_codepoint_t) num_glyphs - gid;
 
+      mapping->alloc (mapping->get_population () + end - start + 1);
+
       for (unsigned cp = start; cp <= end; cp++)
       {
         unicodes->add (cp);
         mapping->set (cp, gid);
-        gid++;
+        gid += T::increment;
       }
     }
   }
@@ -794,6 +795,9 @@
 
 struct CmapSubtableFormat12 : CmapSubtableLongSegmented
 {
+  static constexpr int increment = 1;
+  static constexpr int formatNumber = 12;
+
   static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
                                          hb_codepoint_t u)
   { return likely (group.startCharCode <= group.endCharCode) ?
@@ -866,6 +870,9 @@
 
 struct CmapSubtableFormat13 : CmapSubtableLongSegmented
 {
+  static constexpr int increment = 0;
+  static constexpr int formatNumber = 13;
+
   static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
                                          hb_codepoint_t u HB_UNUSED)
   { return group.glyphID; }
@@ -917,8 +924,7 @@
   DefaultUVS* copy (hb_serialize_context_t *c,
                     const hb_set_t *unicodes) const
   {
-    DefaultUVS *out = c->start_embed ();
-    if (unlikely (!out)) return nullptr;
+    auto *out = c->start_embed ();
     auto snap = c->snapshot ();
 
     HBUINT32 len;
@@ -931,8 +937,7 @@
       hb_codepoint_t start = HB_SET_VALUE_INVALID;
       hb_codepoint_t end = HB_SET_VALUE_INVALID;
 
-      for (hb_codepoint_t u = HB_SET_VALUE_INVALID;
-           unicodes->next (&u);)
+      for (auto u : *unicodes)
       {
         if (!as_array ().bsearch (u))
           continue;
@@ -1067,9 +1072,7 @@
                        const hb_set_t *glyphs_requested,
                        const hb_map_t *glyph_map) const
   {
-    NonDefaultUVS *out = c->start_embed ();
-    if (unlikely (!out)) return nullptr;
-
+    auto *out = c->start_embed ();
     auto it =
     + as_array ()
     | hb_filter ([&] (const UVSMapping& _)
@@ -1767,7 +1770,6 @@
     TRACE_SUBSET (this);
 
     cmap *cmap_prime = c->serializer->start_embed ();
-    if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false);
 
     auto encodingrec_iter =
     + hb_iter (encodingRecord)
@@ -1798,7 +1800,7 @@
 
     auto it =
     + c->plan->unicode_to_new_gid_list.iter ()
-    | hb_filter ([&] (const hb_pair_t _)
+    | hb_filter ([&] (const hb_codepoint_pair_t _)
                  { return (_.second != HB_MAP_VALUE_INVALID); })
     ;
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc	2024-01-16 16:19:00.000000000 +0000
@@ -38,8 +38,8 @@
 
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
-#include "hb-ot-cff1-table.hh"
 #include "hb-ot-cff2-table.hh"
+#include "hb-ot-cff1-table.hh"
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-post-table.hh"
 #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
@@ -64,13 +64,17 @@
 using hb_ot_font_cmap_cache_t    = hb_cache_t<21, 16, 8, true>;
 using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
 
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
 static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
+#endif
 
 struct hb_ot_font_t
 {
   const hb_ot_face_t *ot_face;
 
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
   hb_ot_font_cmap_cache_t *cmap_cache;
+#endif
 
   /* h_advance caching */
   mutable hb_atomic_int_t cached_coords_serial;
@@ -86,6 +90,7 @@
 
   ot_font->ot_face = &font->face->table;
 
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
   // retry:
   auto *cmap_cache  = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
                                                                          &hb_ot_font_cmap_cache_user_data_key);
@@ -93,7 +98,7 @@
   {
     cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
     if (unlikely (!cmap_cache)) goto out;
-    cmap_cache->init ();
+    new (cmap_cache) hb_ot_font_cmap_cache_t ();
     if (unlikely (!hb_face_set_user_data (font->face,
                                           &hb_ot_font_cmap_cache_user_data_key,
                                           cmap_cache,
@@ -112,6 +117,7 @@
   }
   out:
   ot_font->cmap_cache = cmap_cache;
+#endif
 
   return ot_font;
 }
@@ -136,7 +142,11 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
-  return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache);
+  hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+  cmap_cache = ot_font->cmap_cache;
+#endif
+  return ot_face->cmap->get_nominal_glyph (unicode, glyph, cmap_cache);
 }
 
 static unsigned int
@@ -151,10 +161,14 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
+  hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+  cmap_cache = ot_font->cmap_cache;
+#endif
   return ot_face->cmap->get_nominal_glyphs (count,
                                             first_unicode, unicode_stride,
                                             first_glyph, glyph_stride,
-                                            ot_font->cmap_cache);
+                                            cmap_cache);
 }
 
 static hb_bool_t
@@ -167,9 +181,13 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
+  hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+  cmap_cache = ot_font->cmap_cache;
+#endif
   return ot_face->cmap->get_variation_glyph (unicode,
                                              variation_selector, glyph,
-                                             ot_font->cmap_cache);
+                                             cmap_cache);
 }
 
 static void
@@ -188,7 +206,7 @@
 
   hb_position_t *orig_first_advance = first_advance;
 
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
   const OT::HVAR &HVAR = *hmtx.var_table;
   const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
   OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
@@ -212,8 +230,8 @@
         use_cache = false;
         goto out;
       }
+      new (cache) hb_ot_font_advance_cache_t;
 
-      cache->init ();
       if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
       {
         hb_free (cache);
@@ -237,7 +255,7 @@
   { /* Use cache. */
     if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords)
     {
-      ot_font->advance_cache->init ();
+      ot_font->advance_cache->clear ();
       ot_font->cached_coords_serial.set_release (font->serial_coords);
     }
 
@@ -258,7 +276,7 @@
     }
   }
 
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
   OT::VariationStore::destroy_cache (varStore_cache);
 #endif
 
@@ -293,7 +311,7 @@
 
   if (vmtx.has_data ())
   {
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
     const OT::VVAR &VVAR = *vmtx.var_table;
     const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
     OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
@@ -308,7 +326,7 @@
       first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride);
     }
 
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
     OT::VariationStore::destroy_cache (varStore_cache);
 #endif
   }
@@ -418,8 +436,8 @@
 #endif
   if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
 #ifndef HB_NO_OT_FONT_CFF
-  if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
   if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
+  if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
 #endif
 
   return false;
@@ -507,8 +525,8 @@
                                     embolden ? &outline : draw_data, font->slant_xy);
     if (!font->face->table.glyf->get_path (font, glyph, draw_session))
 #ifndef HB_NO_CFF
-    if (!font->face->table.cff1->get_path (font, glyph, draw_session))
     if (!font->face->table.cff2->get_path (font, glyph, draw_session))
+    if (!font->face->table.cff1->get_path (font, glyph, draw_session))
 #endif
     {}
   }
@@ -547,8 +565,8 @@
 #endif
   if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
 #ifndef HB_NO_CFF
-  if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
   if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
+  if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
 #endif
 }
 #endif
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -46,21 +46,23 @@
 
   template
-  bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it)
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned pixelSize,
+                  Iterator it,
+                  const hb_vector_t new_to_old_gid_list,
+                  unsigned num_glyphs)
   {
     TRACE_SERIALIZE (this);
 
-    unsigned length = it.len ();
-
-    if (unlikely (!c->extend (this, length)))  return_trace (false);
+    if (unlikely (!c->extend (this, num_glyphs)))  return_trace (false);
 
     this->pixelSize = pixelSize;
     this->maxWidth =
     + it
     | hb_reduce (hb_max, 0u);
 
-    + it
-    | hb_sink (widthsZ.as_array (length));
+    for (auto &_ : new_to_old_gid_list)
+      widthsZ[_.first] = *it++;
 
     return_trace (true);
   }
@@ -89,7 +91,11 @@
 
   template
-  bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it)
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned version,
+                  Iterator it,
+                  const hb_vector_t &new_to_old_gid_list,
+                  unsigned num_glyphs)
   {
     TRACE_SERIALIZE (this);
 
@@ -97,10 +103,10 @@
 
     this->version = version;
     this->numRecords = it.len ();
-    this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0);
+    this->sizeDeviceRecord = DeviceRecord::get_size (num_glyphs);
 
     for (const hb_item_type& _ : +it)
-      c->start_embed ()->serialize (c, _.first, _.second);
+      c->start_embed ()->serialize (c, _.first, _.second, new_to_old_gid_list, num_glyphs);
 
     return_trace (c->successful ());
   }
@@ -110,31 +116,30 @@
   {
     TRACE_SUBSET (this);
 
-    hdmx *hdmx_prime = c->serializer->start_embed  ();
-    if (unlikely (!hdmx_prime)) return_trace (false);
+    auto *hdmx_prime = c->serializer->start_embed  ();
 
+    unsigned num_input_glyphs = get_num_glyphs ();
     auto it =
     + hb_range ((unsigned) numRecords)
-    | hb_map ([c, this] (unsigned _)
+    | hb_map ([c, num_input_glyphs, this] (unsigned _)
         {
           const DeviceRecord *device_record =
             &StructAtOffset (&firstDeviceRecord,
                                            _ * sizeDeviceRecord);
           auto row =
-            + hb_range (c->plan->num_output_glyphs ())
-            | hb_map (c->plan->reverse_glyph_map)
-            | hb_map ([this, c, device_record] (hb_codepoint_t _)
+            + hb_iter (c->plan->new_to_old_gid_list)
+            | hb_map ([num_input_glyphs, device_record] (hb_codepoint_pair_t _)
                       {
-                        if (c->plan->is_empty_glyph (_))
-                          return Null (HBUINT8);
-                        return device_record->widthsZ.as_array (get_num_glyphs ()) [_];
+                        return device_record->widthsZ.as_array (num_input_glyphs) [_.second];
                       })
             ;
           return hb_pair ((unsigned) device_record->pixelSize, +row);
         })
     ;
 
-    hdmx_prime->serialize (c->serializer, version, it);
+    hdmx_prime->serialize (c->serializer, version, it,
+                           c->plan->new_to_old_gid_list,
+                           c->plan->num_output_glyphs ());
     return_trace (true);
   }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -83,7 +83,7 @@
   bool subset_update_header (hb_subset_context_t *c,
                              unsigned int num_hmetrics,
                              const hb_hashmap_t> *mtx_map,
-                             const hb_map_t *bounds_map) const
+                             const hb_vector_t &bounds_vec) const
   {
     hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table (c->plan->source, H::tableTag);
     hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
@@ -114,6 +114,7 @@
         HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET,   caretOffset);
       }
 
+      bool empty = true;
       int min_lsb = 0x7FFF;
       int min_rsb = 0x7FFF;
       int max_extent = -0x7FFF;
@@ -125,9 +126,10 @@
         int lsb = _.second.second;
         max_adv = hb_max (max_adv, adv);
 
-        if (bounds_map->has (gid))
+        if (bounds_vec[gid] != 0xFFFFFFFF)
         {
-          unsigned bound_width = bounds_map->get (gid);
+          empty = false;
+          unsigned bound_width = bounds_vec[gid];
           int rsb = adv - lsb - bound_width;
           int extent = lsb + bound_width;
           min_lsb = hb_min (min_lsb, lsb);
@@ -137,7 +139,7 @@
       }
 
       table->advanceMax = max_adv;
-      if (!bounds_map->is_empty ())
+      if (!empty)
       {
         table->minLeadingBearing = min_lsb;
         table->minTrailingBearing = min_rsb;
@@ -156,32 +158,32 @@
            hb_requires (hb_is_iterator (Iterator))>
   void serialize (hb_serialize_context_t *c,
                   Iterator it,
-                  unsigned num_long_metrics)
+                  const hb_vector_t new_to_old_gid_list,
+                  unsigned num_long_metrics,
+                  unsigned total_num_metrics)
   {
-    unsigned idx = 0;
-    for (auto _ : it)
+    LongMetric* long_metrics = c->allocate_size (num_long_metrics * LongMetric::static_size);
+    FWORD* short_metrics = c->allocate_size ((total_num_metrics - num_long_metrics) * FWORD::static_size);
+    if (!long_metrics || !short_metrics) return;
+
+    short_metrics -= num_long_metrics;
+
+    for (auto _ : new_to_old_gid_list)
     {
-      if (idx < num_long_metrics)
+      hb_codepoint_t gid = _.first;
+      auto mtx = *it++;
+
+      if (gid < num_long_metrics)
       {
-        LongMetric lm;
-        lm.advance = _.first;
-        lm.sb = _.second;
-        if (unlikely (!c->embed (&lm))) return;
-      }
-      else if (idx < 0x10000u)
-      {
-        FWORD *sb = c->allocate_size (FWORD::static_size);
-        if (unlikely (!sb)) return;
-        *sb = _.second;
-      }
+        LongMetric& lm = long_metrics[gid];
+        lm.advance = mtx.first;
+        lm.sb = mtx.second;
+      }
+      // TODO(beyond-64k): This assumes that maxp.numGlyphs is 0xFFFF.
+      else if (gid < 0x10000u)
+        short_metrics[gid] = mtx.second;
       else
-      {
-        // TODO: This does not do tail optimization.
-        UFWORD *adv = c->allocate_size (UFWORD::static_size);
-        if (unlikely (!adv)) return;
-        *adv = _.first;
-      }
-      idx++;
+        ((UFWORD*) short_metrics)[gid] = mtx.first;
     }
   }
 
@@ -189,8 +191,7 @@
   {
     TRACE_SUBSET (this);
 
-    T *table_prime = c->serializer->start_embed  ();
-    if (unlikely (!table_prime)) return_trace (false);
+    auto *table_prime = c->serializer->start_embed  ();
 
     accelerator_t _mtx (c->plan->source);
     unsigned num_long_metrics;
@@ -199,6 +200,8 @@
       /* Determine num_long_metrics to encode. */
       auto& plan = c->plan;
 
+      // TODO Don't consider retaingid holes here.
+
       num_long_metrics = hb_min (plan->num_output_glyphs (), 0xFFFFu);
       unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx);
       while (num_long_metrics > 1 &&
@@ -209,31 +212,36 @@
     }
 
     auto it =
-    + hb_range (c->plan->num_output_glyphs ())
-    | hb_map ([c, &_mtx, mtx_map] (unsigned _)
+    + hb_iter (c->plan->new_to_old_gid_list)
+    | hb_map ([c, &_mtx, mtx_map] (hb_codepoint_pair_t _)
               {
-                if (!mtx_map->has (_))
+                hb_codepoint_t new_gid = _.first;
+                hb_codepoint_t old_gid = _.second;
+
+                hb_pair_t *v = nullptr;
+                if (!mtx_map->has (new_gid, &v))
                 {
-                  hb_codepoint_t old_gid;
-                  if (!c->plan->old_gid_for_new_gid (_, &old_gid))
-                    return hb_pair (0u, 0);
                   int lsb = 0;
                   if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
                     (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb);
                   return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb);
                 }
-                return mtx_map->get (_);
+                return *v;
               })
     ;
 
-    table_prime->serialize (c->serializer, it, num_long_metrics);
+    table_prime->serialize (c->serializer,
+                            it,
+                            c->plan->new_to_old_gid_list,
+                            num_long_metrics,
+                            c->plan->num_output_glyphs ());
 
     if (unlikely (c->serializer->in_error ()))
       return_trace (false);
 
     // Amend header num hmetrics
     if (unlikely (!subset_update_header (c, num_long_metrics, mtx_map,
-                                         T::is_horizontal ? &c->plan->bounds_width_map : &c->plan->bounds_height_map)))
+                                         T::is_horizontal ? c->plan->bounds_width_vec : c->plan->bounds_height_vec)))
       return_trace (false);
 
     return_trace (true);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -170,8 +170,8 @@
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-                          minCoord.sanitize (c, this) &&
-                          maxCoord.sanitize (c, this)));
+                          minCoord.sanitize (c, base) &&
+                          maxCoord.sanitize (c, base)));
   }
 
   protected:
@@ -187,7 +187,6 @@
                                  * of MinMax table (may be NULL) */
   public:
   DEFINE_SIZE_STATIC (8);
-
 };
 
 struct MinMax
@@ -274,7 +273,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-                          minMax.sanitize (c, this)));
+                          minMax.sanitize (c, base)));
   }
 
   protected:
@@ -297,7 +296,8 @@
   const BaseCoord &get_base_coord (int baseline_tag_index) const
   { return (this+baseValues).get_base_coord (baseline_tag_index); }
 
-  bool has_data () const { return baseValues; }
+  bool has_values () const { return baseValues; }
+  bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -383,7 +383,7 @@
                      const BaseCoord **coord) const
   {
     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
-    if (!base_script.has_data ())
+    if (!base_script.has_values ())
     {
       *coord = nullptr;
       return false;
@@ -410,7 +410,7 @@
                     const BaseCoord **max_coord) const
   {
     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
-    if (!base_script.has_data ())
+    if (!base_script.has_min_max ())
     {
       *min_coord = *max_coord = nullptr;
       return false;
@@ -425,8 +425,8 @@
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-                          (this+baseTagList).sanitize (c) &&
-                          (this+baseScriptList).sanitize (c)));
+                          baseTagList.sanitize (c, this) &&
+                          baseScriptList.sanitize (c, this)));
   }
 
   protected:
@@ -473,14 +473,13 @@
     return true;
   }
 
-  /* TODO: Expose this separately sometime? */
   bool get_min_max (hb_font_t      *font,
                     hb_direction_t  direction,
                     hb_tag_t        script_tag,
                     hb_tag_t        language_tag,
                     hb_tag_t        feature_tag,
                     hb_position_t  *min,
-                    hb_position_t  *max)
+                    hb_position_t  *max) const
   {
     const BaseCoord *min_coord, *max_coord;
     if (!get_axis (direction).get_min_max (script_tag, language_tag, feature_tag,
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -55,19 +55,22 @@
     hb_serialize_context_t *c,
     const hb_set_t &klasses,
     bool use_class_zero,
-    hb_sorted_vector_t> &glyph_and_klass, /* IN/OUT */
+    hb_sorted_vector_t &glyph_and_klass, /* IN/OUT */
     hb_map_t *klass_map /*IN/OUT*/);
 
 struct hb_collect_feature_substitutes_with_var_context_t
 {
   const hb_map_t *axes_index_tag_map;
-  const hb_hashmap_t *axes_location;
+  const hb_hashmap_t *axes_location;
   hb_hashmap_t> *record_cond_idx_map;
   hb_hashmap_t *feature_substitutes_map;
+  bool& insert_catch_all_feature_variation_record;
 
   // not stored in subset_plan
   hb_set_t *feature_indices;
   bool apply;
+  bool variation_applied;
+  bool universal;
   unsigned cur_record_idx;
   hb_hashmap_t, unsigned> *conditionset_map;
 };
@@ -188,27 +191,15 @@
   static return_t default_return_value () { return hb_empty_t (); }
 
   hb_set_t *layout_variation_indices;
-  hb_hashmap_t> *varidx_delta_map;
-  hb_font_t *font;
-  const VariationStore *var_store;
   const hb_set_t *glyph_set;
   const hb_map_t *gpos_lookups;
-  float *store_cache;
 
   hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_,
-                                          hb_hashmap_t> *varidx_delta_map_,
-                                          hb_font_t *font_,
-                                          const VariationStore *var_store_,
                                           const hb_set_t *glyph_set_,
-                                          const hb_map_t *gpos_lookups_,
-                                          float *store_cache_) :
+                                          const hb_map_t *gpos_lookups_) :
                                         layout_variation_indices (layout_variation_indices_),
-                                        varidx_delta_map (varidx_delta_map_),
-                                        font (font_),
-                                        var_store (var_store_),
                                         glyph_set (glyph_set_),
-                                        gpos_lookups (gpos_lookups_),
-                                        store_cache (store_cache_) {}
+                                        gpos_lookups (gpos_lookups_) {}
 };
 
 template
@@ -807,7 +798,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     out->featureParams.serialize_subset (c, featureParams, this, tag);
 
@@ -981,7 +972,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     + hb_enumerate (*this)
     | hb_filter (l->feature_index_map, hb_first)
@@ -1078,7 +1069,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     const uint32_t *v;
     out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
@@ -1188,7 +1179,7 @@
       return false;
 
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     bool defaultLang = false;
     if (has_default_lang_sys ())
@@ -1247,7 +1238,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     for (auto _ : + hb_enumerate (*this))
     {
@@ -1367,7 +1358,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
     out->lookupType = lookupType;
     out->lookupFlag = lookupFlag;
 
@@ -1456,7 +1447,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     + hb_enumerate (*this)
     | hb_filter (l->lookup_index_map, hb_first)
@@ -1482,7 +1473,7 @@
 static bool ClassDef_remap_and_serialize (hb_serialize_context_t *c,
                                           const hb_set_t &klasses,
                                           bool use_class_zero,
-                                          hb_sorted_vector_t> &glyph_and_klass, /* IN/OUT */
+                                          hb_sorted_vector_t &glyph_and_klass, /* IN/OUT */
                                           hb_map_t *klass_map /*IN/OUT*/)
 {
   if (!klass_map)
@@ -1573,7 +1564,7 @@
     TRACE_SUBSET (this);
     const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
 
-    hb_sorted_vector_t> glyph_and_klass;
+    hb_sorted_vector_t glyph_and_klass;
     hb_set_t orig_klasses;
 
     hb_codepoint_t start = startGlyph;
@@ -1592,10 +1583,13 @@
       orig_klasses.add (klass);
     }
 
-    unsigned glyph_count = glyph_filter
-                           ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter))
-                           : glyph_map.get_population ();
-    use_class_zero = use_class_zero && glyph_count <= glyph_and_klass.length;
+    if (use_class_zero)
+    {
+      unsigned glyph_count = glyph_filter
+                             ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter))
+                             : glyph_map.get_population ();
+      use_class_zero = glyph_count <= glyph_and_klass.length;
+    }
     if (!ClassDef_remap_and_serialize (c->serializer,
                                        orig_klasses,
                                        use_class_zero,
@@ -1769,6 +1763,7 @@
       return_trace (true);
     }
 
+    unsigned unsorted = false;
     unsigned num_ranges = 1;
     hb_codepoint_t prev_gid = (*it).first;
     unsigned prev_klass = (*it).second;
@@ -1789,6 +1784,10 @@
       if (cur_gid != prev_gid + 1 ||
           cur_klass != prev_klass)
       {
+
+        if (unlikely (cur_gid < prev_gid))
+          unsorted = true;
+
         if (unlikely (!record)) break;
         record->last = prev_gid;
         num_ranges++;
@@ -1804,8 +1803,14 @@
       prev_gid = cur_gid;
     }
 
+    if (unlikely (c->in_error ())) return_trace (false);
+
     if (likely (record)) record->last = prev_gid;
     rangeRecord.len = num_ranges;
+
+    if (unlikely (unsorted))
+      rangeRecord.as_array ().qsort (RangeRecord::cmp_range);
+
     return_trace (true);
   }
 
@@ -1819,7 +1824,7 @@
     const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
     const hb_set_t &glyph_set = *c->plan->glyphset_gsub ();
 
-    hb_sorted_vector_t> glyph_and_klass;
+    hb_sorted_vector_t glyph_and_klass;
     hb_set_t orig_klasses;
 
     if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2
@@ -1905,7 +1910,7 @@
   {
     if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      for (auto g : *glyphs)
         if (get_class (g))
           return true;
       return false;
@@ -1920,13 +1925,22 @@
     {
       /* Match if there's any glyph that is not listed! */
       hb_codepoint_t g = HB_SET_VALUE_INVALID;
-      for (auto &range : rangeRecord)
+      hb_codepoint_t last = HB_SET_VALUE_INVALID;
+      auto it = hb_iter (rangeRecord);
+      for (auto &range : it)
       {
+        if (it->first == last + 1)
+        {
+          it++;
+          continue;
+        }
+
         if (!glyphs->next (&g))
           break;
         if (g < range.first)
           return true;
         g = range.last;
+        last = g;
       }
       if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
         return true;
@@ -1965,8 +1979,7 @@
     unsigned count = rangeRecord.len;
     if (count > glyphs->get_population () * hb_bit_storage (count) * 8)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID;
-           glyphs->next (&g);)
+      for (auto g : *glyphs)
       {
         unsigned i;
         if (rangeRecord.as_array ().bfind (g, &i) &&
@@ -2097,8 +2110,15 @@
 
 #ifndef HB_NO_BEYOND_64K
     if (glyph_max > 0xFFFFu)
-      format += 2;
+      u.format += 2;
+    if (unlikely (glyph_max > 0xFFFFFFu))
+#else
+    if (unlikely (glyph_max > 0xFFFFu))
 #endif
+    {
+      c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+      return_trace (false);
+    }
 
     u.format = format;
 
@@ -2268,6 +2288,158 @@
  * Item Variation Store
  */
 
+/* ported from fonttools (class _Encoding) */
+struct delta_row_encoding_t
+{
+  /* each byte represents a region, value is one of 0/1/2/4, which means bytes
+   * needed for this region */
+  hb_vector_t chars;
+  unsigned width = 0;
+  hb_vector_t columns;
+  unsigned overhead = 0;
+  hb_vector_t*> items;
+
+  delta_row_encoding_t () = default;
+  delta_row_encoding_t (hb_vector_t&& chars_,
+                        const hb_vector_t* row = nullptr) :
+                        delta_row_encoding_t ()
+
+  {
+    chars = std::move (chars_);
+    width = get_width ();
+    columns = get_columns ();
+    overhead = get_chars_overhead (columns);
+    if (row) items.push (row);
+  }
+
+  bool is_empty () const
+  { return !items; }
+
+  static hb_vector_t get_row_chars (const hb_vector_t& row)
+  {
+    hb_vector_t ret;
+    if (!ret.alloc (row.length)) return ret;
+
+    bool long_words = false;
+
+    /* 0/1/2 byte encoding */
+    for (int i = row.length - 1; i >= 0; i--)
+    {
+      int v =  row.arrayZ[i];
+      if (v == 0)
+        ret.push (0);
+      else if (v > 32767 || v < -32768)
+      {
+        long_words = true;
+        break;
+      }
+      else if (v > 127 || v < -128)
+        ret.push (2);
+      else
+        ret.push (1);
+    }
+
+    if (!long_words)
+      return ret;
+
+    /* redo, 0/2/4 bytes encoding */
+    ret.reset ();
+    for (int i = row.length - 1; i >= 0; i--)
+    {
+      int v =  row.arrayZ[i];
+      if (v == 0)
+        ret.push (0);
+      else if (v > 32767 || v < -32768)
+        ret.push (4);
+      else
+        ret.push (2);
+    }
+    return ret;
+  }
+
+  inline unsigned get_width ()
+  {
+    unsigned ret = + hb_iter (chars)
+                   | hb_reduce (hb_add, 0u)
+                   ;
+    return ret;
+  }
+
+  hb_vector_t get_columns ()
+  {
+    hb_vector_t cols;
+    cols.alloc (chars.length);
+    for (auto v : chars)
+    {
+      uint8_t flag = v ? 1 : 0;
+      cols.push (flag);
+    }
+    return cols;
+  }
+
+  static inline unsigned get_chars_overhead (const hb_vector_t& cols)
+  {
+    unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header
+    unsigned cols_bit_count = 0;
+    for (auto v : cols)
+      if (v) cols_bit_count++;
+    return c + cols_bit_count * 2;
+  }
+
+  unsigned get_gain () const
+  {
+    int count = items.length;
+    return hb_max (0, (int) overhead - count);
+  }
+
+  int gain_from_merging (const delta_row_encoding_t& other_encoding) const
+  {
+    int combined_width = 0;
+    for (unsigned i = 0; i < chars.length; i++)
+      combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]);
+
+    hb_vector_t combined_columns;
+    combined_columns.alloc (columns.length);
+    for (unsigned i = 0; i < columns.length; i++)
+      combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]);
+
+    int combined_overhead = get_chars_overhead (combined_columns);
+    int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead
+                        - (combined_width - (int) width) * items.length
+                        - (combined_width - (int) other_encoding.width) * other_encoding.items.length;
+
+    return combined_gain;
+  }
+
+  static int cmp (const void *pa, const void *pb)
+  {
+    const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa;
+    const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb;
+
+    int gain_a = a->get_gain ();
+    int gain_b = b->get_gain ();
+
+    if (gain_a != gain_b)
+      return gain_a - gain_b;
+
+    return (b->chars).as_array ().cmp ((a->chars).as_array ());
+  }
+
+  static int cmp_width (const void *pa, const void *pb)
+  {
+    const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa;
+    const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb;
+
+    if (a->width != b->width)
+      return (int) a->width - (int) b->width;
+
+    return (b->chars).as_array ().cmp ((a->chars).as_array ());
+  }
+
+  bool add_row (const hb_vector_t* row)
+  { return items.push (row); }
+};
+
 struct VarRegionAxis
 {
   float evaluate (int coord) const
@@ -2302,6 +2474,12 @@
      * have to do that at runtime. */
   }
 
+  bool serialize (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
   public:
   F2DOT14       startCoord;
   F2DOT14       peakCoord;
@@ -2359,7 +2537,48 @@
     return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount));
   }
 
-  bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t ®ion_map)
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_vector_t& axis_tags,
+                  const hb_vector_t*>& regions)
+  {
+    TRACE_SERIALIZE (this);
+    unsigned axis_count = axis_tags.length;
+    unsigned region_count = regions.length;
+    if (!axis_count || !region_count) return_trace (false);
+    if (unlikely (hb_unsigned_mul_overflows (axis_count * region_count,
+                                             VarRegionAxis::static_size))) return_trace (false);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    axisCount = axis_count;
+    regionCount = region_count;
+
+    for (unsigned r = 0; r < region_count; r++)
+    {
+      const auto& region = regions[r];
+      for (unsigned i = 0; i < axis_count; i++)
+      {
+        hb_tag_t tag = axis_tags.arrayZ[i];
+        VarRegionAxis var_region_rec;
+        Triple *coords;
+        if (region->has (tag, &coords))
+        {
+          var_region_rec.startCoord.set_float (coords->minimum);
+          var_region_rec.peakCoord.set_float (coords->middle);
+          var_region_rec.endCoord.set_float (coords->maximum);
+        }
+        else
+        {
+          var_region_rec.startCoord.set_int (0);
+          var_region_rec.peakCoord.set_int (0);
+          var_region_rec.endCoord.set_int (0);
+        }
+        if (!var_region_rec.serialize (c))
+          return_trace (false);
+      }
+    }
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_inc_bimap_t ®ion_map)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -2379,6 +2598,45 @@
     return_trace (true);
   }
 
+  bool get_var_region (unsigned region_index,
+                       const hb_map_t& axes_old_index_tag_map,
+                       hb_hashmap_t& axis_tuples /* OUT */) const
+  {
+    if (region_index >= regionCount) return false;
+    const VarRegionAxis* axis_region = axesZ.arrayZ + (region_index * axisCount);
+    for (unsigned i = 0; i < axisCount; i++)
+    {
+      hb_tag_t *axis_tag;
+      if (!axes_old_index_tag_map.has (i, &axis_tag))
+        return false;
+
+      float min_val = axis_region->startCoord.to_float ();
+      float def_val = axis_region->peakCoord.to_float ();
+      float max_val = axis_region->endCoord.to_float ();
+
+      if (def_val != 0.f)
+        axis_tuples.set (*axis_tag, Triple (min_val, def_val, max_val));
+      axis_region++;
+    }
+    return !axis_tuples.in_error ();
+  }
+
+  bool get_var_regions (const hb_map_t& axes_old_index_tag_map,
+                        hb_vector_t>& regions /* OUT */) const
+  {
+    if (!regions.alloc (regionCount))
+      return false;
+
+    for (unsigned i = 0; i < regionCount; i++)
+    {
+      hb_hashmap_t axis_tuples;
+      if (!get_var_region (i, axes_old_index_tag_map, axis_tuples))
+        return false;
+      regions.push (std::move (axis_tuples));
+    }
+    return !regions.in_error ();
+  }
+
   unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
 
   public:
@@ -2399,6 +2657,9 @@
   unsigned int get_region_index_count () const
   { return regionIndices.len; }
 
+  unsigned get_region_index (unsigned i) const
+  { return i >= regionIndices.len ? -1 : regionIndices[i]; }
+
   unsigned int get_row_size () const
   { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
 
@@ -2474,9 +2735,84 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
+                  bool has_long,
+                  const hb_vector_t*>& rows)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    unsigned row_count = rows.length;
+    itemCount = row_count;
+
+    int min_threshold = has_long ? -65536 : -128;
+    int max_threshold = has_long ? +65535 : +127;
+    enum delta_size_t { kZero=0, kNonWord, kWord };
+    hb_vector_t delta_sz;
+    unsigned num_regions = rows[0]->length;
+    if (!delta_sz.resize (num_regions))
+      return_trace (false);
+
+    unsigned word_count = 0;
+    for (unsigned r = 0; r < num_regions; r++)
+    {
+      for (unsigned i = 0; i < row_count; i++)
+      {
+        int delta = rows[i]->arrayZ[r];
+        if (delta < min_threshold || delta > max_threshold)
+        {
+          delta_sz[r] = kWord;
+          word_count++;
+          break;
+        }
+        else if (delta != 0)
+        {
+          delta_sz[r] = kNonWord;
+        }
+      }
+    }
+
+    /* reorder regions: words and then non-words*/
+    unsigned word_index = 0;
+    unsigned non_word_index = word_count;
+    hb_map_t ri_map;
+    for (unsigned r = 0; r < num_regions; r++)
+    {
+      if (!delta_sz[r]) continue;
+      unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
+      if (!ri_map.set (new_r, r))
+        return_trace (false);
+    }
+
+    wordSizeCount = word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
+
+    unsigned ri_count = ri_map.get_population ();
+    regionIndices.len = ri_count;
+    if (unlikely (!c->extend (this))) return_trace (false);
+
+    for (unsigned r = 0; r < ri_count; r++)
+    {
+      hb_codepoint_t *idx;
+      if (!ri_map.has (r, &idx))
+        return_trace (false);
+      regionIndices[r] = *idx;
+    }
+
+    HBUINT8 *delta_bytes = get_delta_bytes ();
+    unsigned row_size = get_row_size ();
+    for (unsigned int i = 0; i < row_count; i++)
+    {
+      for (unsigned int r = 0; r < ri_count; r++)
+      {
+        int delta = rows[i]->arrayZ[ri_map[r]];
+        set_item_delta_fast (i, r, delta, delta_bytes, row_size);
+      }
+    }
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
                   const VarData *src,
                   const hb_inc_bimap_t &inner_map,
-                  const hb_bimap_t ®ion_map)
+                  const hb_inc_bimap_t ®ion_map)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -2593,13 +2929,15 @@
     }
   }
 
-  protected:
+  public:
   const HBUINT8 *get_delta_bytes () const
   { return &StructAfter (regionIndices); }
 
+  protected:
   HBUINT8 *get_delta_bytes ()
   { return &StructAfter (regionIndices); }
 
+  public:
   int32_t get_item_delta_fast (unsigned int item, unsigned int region,
                                const HBUINT8 *delta_bytes, unsigned row_size) const
   {
@@ -2630,6 +2968,7 @@
                                  get_row_size ());
   }
 
+  protected:
   void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta,
                             HBUINT8 *delta_bytes, unsigned row_size)
   {
@@ -2672,6 +3011,7 @@
 
 struct VariationStore
 {
+  friend struct item_variations_t;
   using cache_t = VarRegionList::cache_t;
 
   cache_t *create_cache () const
@@ -2743,6 +3083,36 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
+                  bool has_long,
+                  const hb_vector_t& axis_tags,
+                  const hb_vector_t*>& region_list,
+                  const hb_vector_t& vardata_encodings)
+  {
+    TRACE_SERIALIZE (this);
+#ifdef HB_NO_VAR
+    return_trace (false);
+#endif
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+
+    format = 1;
+    if (!regions.serialize_serialize (c, axis_tags, region_list))
+      return_trace (false);
+
+    unsigned num_var_data = vardata_encodings.length;
+    if (!num_var_data) return_trace (false);
+    if (unlikely (!c->check_assign (dataSets.len, num_var_data,
+                                    HB_SERIALIZE_ERROR_INT_OVERFLOW)))
+      return_trace (false);
+
+    if (unlikely (!c->extend (dataSets))) return_trace (false);
+    for (unsigned i = 0; i < num_var_data; i++)
+      if (!dataSets[i].serialize_serialize (c, has_long, vardata_encodings[i].items))
+        return_trace (false);
+
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
                   const VariationStore *src,
                   const hb_array_t  &inner_maps)
   {
@@ -2871,6 +3241,22 @@
      return dataSets.len;
    }
 
+  const VarData& get_sub_table (unsigned i) const
+  {
+#ifdef HB_NO_VAR
+     return Null (VarData);
+#endif
+     return this+dataSets[i];
+  }
+
+  const VarRegionList& get_region_list () const
+  {
+#ifdef HB_NO_VAR
+     return Null (VarRegionList);
+#endif
+     return this+regions;
+  }
+
   protected:
   HBUINT16                              format;
   Offset32To             regions;
@@ -2887,9 +3273,9 @@
 enum Cond_with_Var_flag_t
 {
   KEEP_COND_WITH_VAR = 0,
-  DROP_COND_WITH_VAR = 1,
-  DROP_RECORD_WITH_VAR = 2,
-  MEM_ERR_WITH_VAR = 3,
+  KEEP_RECORD_WITH_VAR = 1,
+  DROP_COND_WITH_VAR = 2,
+  DROP_RECORD_WITH_VAR = 3,
 };
 
 struct ConditionFormat1
@@ -2905,9 +3291,29 @@
     const hb_map_t *index_map = &c->plan->axes_index_map;
     if (index_map->is_empty ()) return_trace (true);
 
-    if (!index_map->has (axisIndex))
+    const hb_map_t& axes_old_index_tag_map = c->plan->axes_old_index_tag_map;
+    hb_codepoint_t *axis_tag;
+    if (!axes_old_index_tag_map.has (axisIndex, &axis_tag) ||
+        !index_map->has (axisIndex))
       return_trace (false);
 
+    const hb_hashmap_t& normalized_axes_location = c->plan->axes_location;
+    Triple axis_limit{-1.f, 0.f, 1.f};
+    Triple *normalized_limit;
+    if (normalized_axes_location.has (*axis_tag, &normalized_limit))
+      axis_limit = *normalized_limit;
+
+    const hb_hashmap_t& axes_triple_distances = c->plan->axes_triple_distances;
+    TripleDistances axis_triple_distances{1.f, 1.f};
+    TripleDistances *triple_dists;
+    if (axes_triple_distances.has (*axis_tag, &triple_dists))
+      axis_triple_distances = *triple_dists;
+
+    float normalized_min = renormalizeValue (filterRangeMinValue.to_float (), axis_limit, axis_triple_distances, false);
+    float normalized_max = renormalizeValue (filterRangeMaxValue.to_float (), axis_limit, axis_triple_distances, false);
+    out->filterRangeMinValue.set_float (normalized_min);
+    out->filterRangeMaxValue.set_float (normalized_max);
+
     return_trace (c->serializer->check_assign (out->axisIndex, index_map->get (axisIndex),
                                                HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
@@ -2922,29 +3328,45 @@
 
     hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
 
-    //axis not pinned, keep the condition
-    if (!c->axes_location->has (axis_tag))
+    Triple axis_range (-1.f, 0.f, 1.f);
+    Triple *axis_limit;
+    if (c->axes_location->has (axis_tag, &axis_limit))
+      axis_range = *axis_limit;
+
+    float axis_min_val = axis_range.minimum;
+    float axis_default_val = axis_range.middle;
+    float axis_max_val = axis_range.maximum;
+
+    float filter_min_val = filterRangeMinValue.to_float ();
+    float filter_max_val = filterRangeMaxValue.to_float ();
+
+    if (axis_default_val < filter_min_val ||
+        axis_default_val > filter_max_val)
+      c->apply = false;
+
+    //condition not met, drop the entire record
+    if (axis_min_val > filter_max_val || axis_max_val < filter_min_val ||
+        filter_min_val > filter_max_val)
+      return DROP_RECORD_WITH_VAR;
+
+    //condition met and axis pinned, drop the condition
+    if (c->axes_location->has (axis_tag) &&
+        c->axes_location->get (axis_tag).is_point ())
+      return DROP_COND_WITH_VAR;
+
+    if (filter_max_val != axis_max_val || filter_min_val != axis_min_val)
     {
       // add axisIndex->value into the hashmap so we can check if the record is
       // unique with variations
-      int16_t min_val = filterRangeMinValue.to_int ();
-      int16_t max_val = filterRangeMaxValue.to_int ();
-      hb_codepoint_t val = (max_val << 16) + min_val;
+      int16_t int_filter_max_val = filterRangeMaxValue.to_int ();
+      int16_t int_filter_min_val = filterRangeMinValue.to_int ();
+      hb_codepoint_t val = (int_filter_max_val << 16) + int_filter_min_val;
 
       condition_map->set (axisIndex, val);
       return KEEP_COND_WITH_VAR;
     }
 
-    //axis pinned, check if condition is met
-    //TODO: add check for axis Ranges
-    int v = c->axes_location->get (axis_tag);
-
-    //condition not met, drop the entire record
-    if (v < filterRangeMinValue.to_int () || v > filterRangeMaxValue.to_int ())
-      return DROP_RECORD_WITH_VAR;
-
-    //axis pinned and condition met, drop the condition
-    return DROP_COND_WITH_VAR;
+    return KEEP_RECORD_WITH_VAR;
   }
 
   bool evaluate (const int *coords, unsigned int coord_len) const
@@ -2983,7 +3405,7 @@
   {
     switch (u.format) {
     case 1: return u.format1.keep_with_variations (c, condition_map);
-    default:return KEEP_COND_WITH_VAR;
+    default: c->apply = false; return KEEP_COND_WITH_VAR;
     }
   }
 
@@ -3028,45 +3450,50 @@
     return true;
   }
 
-  Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
+  void keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
   {
     hb_map_t *condition_map = hb_map_create ();
-    if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR;
+    if (unlikely (!condition_map)) return;
     hb::shared_ptr p {condition_map};
 
     hb_set_t *cond_set = hb_set_create ();
-    if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR;
+    if (unlikely (!cond_set)) return;
     hb::shared_ptr s {cond_set};
 
+    c->apply = true;
+    bool should_keep = false;
     unsigned num_kept_cond = 0, cond_idx = 0;
     for (const auto& offset : conditions)
     {
       Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map);
-      // one condition is not met, drop the entire record
+      // condition is not met or condition out of range, drop the entire record
       if (ret == DROP_RECORD_WITH_VAR)
-        return DROP_RECORD_WITH_VAR;
+        return;
 
-      // axis not pinned, keep this condition
       if (ret == KEEP_COND_WITH_VAR)
       {
+        should_keep = true;
         cond_set->add (cond_idx);
         num_kept_cond++;
       }
+
+      if (ret == KEEP_RECORD_WITH_VAR)
+        should_keep = true;
+
       cond_idx++;
     }
 
-    // all conditions met
-    if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
+    if (!should_keep) return;
 
     //check if condition_set is unique with variations
     if (c->conditionset_map->has (p))
       //duplicate found, drop the entire record
-      return DROP_RECORD_WITH_VAR;
+      return;
 
     c->conditionset_map->set (p, 1);
     c->record_cond_idx_map->set (c->cur_record_idx, s);
-
-    return KEEP_COND_WITH_VAR;
+    if (should_keep && num_kept_cond == 0)
+      c->universal = true;
   }
 
   bool subset (hb_subset_context_t *c,
@@ -3142,8 +3569,7 @@
     if (unlikely (!out)) return_trace (false);
 
     out->featureIndex = c->feature_index_map->get (featureIndex);
-    bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c);
-    return_trace (ret);
+    return_trace (out->feature.serialize_subset (c->subset_context, feature, base, c));
   }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
@@ -3271,12 +3697,11 @@
   void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
                                                     const void *base) const
   {
-    // ret == 1, all conditions met
-    if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR &&
-        c->apply)
+    (base+conditions).keep_with_variations (c);
+    if (c->apply && !c->variation_applied)
     {
       (base+substitutions).collect_feature_substitutes_with_variations (c);
-      c->apply = false; // set variations only once
+      c->variation_applied = true; // set variations only once
     }
   }
 
@@ -3343,7 +3768,12 @@
     {
       c->cur_record_idx = i;
       varRecords[i].collect_feature_substitutes_with_variations (c, this);
+      if (c->universal)
+        break;
     }
+    if (c->variation_applied && !c->universal &&
+        !c->record_cond_idx_map->is_empty ())
+      c->insert_catch_all_feature_variation_record = true;
   }
 
   FeatureVariations* copy (hb_serialize_context_t *c) const
@@ -3538,22 +3968,13 @@
     auto *out = c->embed (this);
     if (unlikely (!out)) return_trace (nullptr);
 
-    unsigned new_idx = hb_first (*v);
-    out->varIdx = new_idx;
+    if (!c->check_assign (out->varIdx, hb_first (*v), HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (nullptr);
     return_trace (out);
   }
 
   void collect_variation_index (hb_collect_variation_indices_context_t *c) const
-  {
-    c->layout_variation_indices->add (varIdx);
-    int delta = 0;
-    if (c->font && c->var_store)
-      delta = roundf (get_delta (c->font, *c->var_store, c->store_cache));
-
-    /* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap
-     * varidx later*/
-    c->varidx_delta_map->set (varIdx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
-  }
+  { c->layout_variation_indices->add (varIdx); }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh	2024-01-16 16:19:00.000000000 +0000
@@ -143,9 +143,12 @@
     return active_glyphs_stack.tail ();
   }
 
-  hb_set_t& push_cur_active_glyphs ()
+  hb_set_t* push_cur_active_glyphs ()
   {
-    return *active_glyphs_stack.push ();
+    hb_set_t *s = active_glyphs_stack.push ();
+    if (unlikely (active_glyphs_stack.in_error ()))
+      return nullptr;
+    return s;
   }
 
   bool pop_cur_done_glyphs ()
@@ -399,16 +402,6 @@
 {
   struct matcher_t
   {
-    matcher_t () :
-             lookup_props (0),
-             mask (-1),
-             ignore_zwnj (false),
-             ignore_zwj (false),
-             per_syllable (false),
-             syllable {0},
-             match_func (nullptr),
-             match_data (nullptr) {}
-
     typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
 
     void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
@@ -427,6 +420,9 @@
       MATCH_MAYBE
     };
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     may_match_t may_match (hb_glyph_info_t &info,
                            hb_codepoint_t glyph_data) const
     {
@@ -446,6 +442,9 @@
       SKIP_MAYBE
     };
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     may_skip_t may_skip (const hb_ot_apply_context_t *c,
                          const hb_glyph_info_t       &info) const
     {
@@ -461,14 +460,14 @@
     }
 
     protected:
-    unsigned int lookup_props;
-    hb_mask_t mask;
-    bool ignore_zwnj;
-    bool ignore_zwj;
-    bool per_syllable;
-    uint8_t syllable;
-    match_func_t match_func;
-    const void *match_data;
+    unsigned int lookup_props = 0;
+    hb_mask_t mask = -1;
+    bool ignore_zwnj = false;
+    bool ignore_zwj = false;
+    bool per_syllable = false;
+    uint8_t syllable = 0;
+    match_func_t match_func = nullptr;
+    const void *match_data = nullptr;
   };
 
   struct skipping_iterator_t
@@ -476,6 +475,7 @@
     void init (hb_ot_apply_context_t *c_, bool context_match = false)
     {
       c = c_;
+      end = c->buffer->len;
       match_glyph_data16 = nullptr;
 #ifndef HB_NO_BEYOND_64K
       match_glyph_data24 = nullptr;
@@ -489,6 +489,7 @@
       matcher.set_mask (context_match ? -1 : c->lookup_mask);
       /* Per syllable matching is only for GSUB. */
       matcher.set_per_syllable (c->table_index == 0 && c->per_syllable);
+      matcher.set_syllable (0);
     }
     void set_lookup_props (unsigned int lookup_props)
     {
@@ -514,22 +515,34 @@
     }
 #endif
 
-    void reset (unsigned int start_index_,
-                unsigned int num_items_)
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
+    void reset (unsigned int start_index_)
     {
       idx = start_index_;
-      num_items = num_items_;
       end = c->buffer->len;
       matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
     }
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
+    void reset_fast (unsigned int start_index_)
+    {
+      // Doesn't set end or syllable. Used by GPOS which doesn't care / change.
+      idx = start_index_;
+    }
+
     void reject ()
     {
-      num_items++;
       backup_glyph_data ();
     }
 
     matcher_t::may_skip_t
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     may_skip (const hb_glyph_info_t &info) const
     { return matcher.may_skip (c, info); }
 
@@ -539,6 +552,9 @@
       SKIP
     };
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     match_t match (hb_glyph_info_t &info)
     {
       matcher_t::may_skip_t skip = matcher.may_skip (c, info);
@@ -557,14 +573,12 @@
       return SKIP;
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     bool next (unsigned *unsafe_to = nullptr)
     {
-      assert (num_items > 0);
-      /* The alternate condition below is faster at string boundaries,
-       * but produces subpar "unsafe-to-concat" values. */
-      signed stop = (signed) end - (signed) num_items;
-      if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
-        stop = (signed) end - 1;
+      const signed stop = (signed) end - 1;
       while ((signed) idx < stop)
       {
         idx++;
@@ -572,7 +586,6 @@
         {
           case MATCH:
           {
-            num_items--;
             advance_glyph_data ();
             return true;
           }
@@ -590,14 +603,12 @@
         *unsafe_to = end;
       return false;
     }
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     bool prev (unsigned *unsafe_from = nullptr)
     {
-      assert (num_items > 0);
-      /* The alternate condition below is faster at string boundaries,
-       * but produces subpar "unsafe-to-concat" values. */
-      unsigned stop = num_items - 1;
-      if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
-        stop = 1 - 1;
+      const unsigned stop = 0;
       while (idx > stop)
       {
         idx--;
@@ -605,7 +616,6 @@
         {
           case MATCH:
           {
-            num_items--;
             advance_glyph_data ();
             return true;
           }
@@ -624,6 +634,7 @@
       return false;
     }
 
+    HB_ALWAYS_INLINE
     hb_codepoint_t
     get_glyph_data ()
     {
@@ -634,6 +645,7 @@
 #endif
       return 0;
     }
+    HB_ALWAYS_INLINE
     void
     advance_glyph_data ()
     {
@@ -662,7 +674,6 @@
     const HBUINT24 *match_glyph_data24;
 #endif
 
-    unsigned int num_items;
     unsigned int end;
   };
 
@@ -693,8 +704,10 @@
   hb_font_t *font;
   hb_face_t *face;
   hb_buffer_t *buffer;
+  hb_sanitize_context_t sanitizer;
   recurse_func_t recurse_func = nullptr;
   const GDEF &gdef;
+  const GDEF::accelerator_t &gdef_accel;
   const VariationStore &var_store;
   VariationStore::cache_t *var_store_cache;
   hb_set_digest_t digest;
@@ -718,9 +731,11 @@
 
   hb_ot_apply_context_t (unsigned int table_index_,
                          hb_font_t *font_,
-                         hb_buffer_t *buffer_) :
+                         hb_buffer_t *buffer_,
+                         hb_blob_t *table_blob_) :
                         table_index (table_index_),
                         font (font_), face (font->face), buffer (buffer_),
+                        sanitizer (table_blob_),
                         gdef (
 #ifndef HB_NO_OT_LAYOUT
                               *face->table.GDEF->table
@@ -728,6 +743,13 @@
                               Null (GDEF)
 #endif
                              ),
+                        gdef_accel (
+#ifndef HB_NO_OT_LAYOUT
+                              *face->table.GDEF
+#else
+                              Null (GDEF::accelerator_t)
+#endif
+                             ),
                         var_store (gdef.get_var_store ()),
                         var_store_cache (
 #ifndef HB_NO_VAR
@@ -754,10 +776,10 @@
     iter_context.init (this, true);
   }
 
-  void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; last_base = -1; last_base_until = 0; init_iters (); }
-  void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
-  void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
-  void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; init_iters (); }
+  void set_lookup_mask (hb_mask_t mask, bool init = true) { lookup_mask = mask; last_base = -1; last_base_until = 0; if (init) init_iters (); }
+  void set_auto_zwj (bool auto_zwj_, bool init = true) { auto_zwj = auto_zwj_; if (init) init_iters (); }
+  void set_auto_zwnj (bool auto_zwnj_, bool init = true) { auto_zwnj = auto_zwnj_; if (init) init_iters (); }
+  void set_per_syllable (bool per_syllable_, bool init = true) { per_syllable = per_syllable_; if (init) init_iters (); }
   void set_random (bool random_) { random = random_; }
   void set_recurse_func (recurse_func_t func) { recurse_func = func; }
   void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
@@ -778,7 +800,7 @@
      * match_props has the set index.
      */
     if (match_props & LookupFlag::UseMarkFilteringSet)
-      return gdef.mark_set_covers (match_props >> 16, glyph);
+      return gdef_accel.mark_set_covers (match_props >> 16, glyph);
 
     /* The second byte of match_props has the meaning
      * "ignore marks of attachment type different than
@@ -790,10 +812,12 @@
     return true;
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool check_glyph_property (const hb_glyph_info_t *info,
                              unsigned int  match_props) const
   {
-    hb_codepoint_t glyph = info->codepoint;
     unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
 
     /* Not covered, if, for example, glyph class is ligature and
@@ -803,7 +827,7 @@
       return false;
 
     if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
-      return match_properties_mark (glyph, glyph_props, match_props);
+      return match_properties_mark (info->codepoint, glyph_props, match_props);
 
     return true;
   }
@@ -836,7 +860,7 @@
     if (likely (has_glyph_classes))
     {
       props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef.get_glyph_props (glyph_index));
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef_accel.get_glyph_props (glyph_index));
     }
     else if (class_guess)
     {
@@ -884,7 +908,7 @@
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   template 
-  static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
+  static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) )
   template 
   static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
   template 
@@ -1148,6 +1172,10 @@
 }
 
 
+static inline bool match_always (hb_glyph_info_t &info HB_UNUSED, unsigned value HB_UNUSED, const void *data HB_UNUSED)
+{
+  return true;
+}
 static inline bool match_glyph (hb_glyph_info_t &info, unsigned value, const void *data HB_UNUSED)
 {
   return info.codepoint == value;
@@ -1168,6 +1196,28 @@
     info.syllable() = klass;
   return klass == value;
 }
+static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+  unsigned klass = info.syllable() & 0x0F;
+  if (klass < 15)
+    return klass == value;
+  const ClassDef &class_def = *reinterpret_cast(data);
+  klass = class_def.get_class (info.codepoint);
+  if (likely (klass < 15))
+    info.syllable() = (info.syllable() & 0xF0) | klass;
+  return klass == value;
+}
+static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+  unsigned klass = (info.syllable() & 0xF0) >> 4;
+  if (klass < 15)
+    return klass == value;
+  const ClassDef &class_def = *reinterpret_cast(data);
+  klass = class_def.get_class (info.codepoint);
+  if (likely (klass < 15))
+    info.syllable() = (info.syllable() & 0x0F) | (klass << 4);
+  return klass == value;
+}
 static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data)
 {
   Offset16To coverage;
@@ -1196,14 +1246,17 @@
   return true;
 }
 template 
-static inline bool match_input (hb_ot_apply_context_t *c,
-                                unsigned int count, /* Including the first glyph (not matched) */
-                                const HBUINT input[], /* Array of input values--start with second glyph */
-                                match_func_t match_func,
-                                const void *match_data,
-                                unsigned int *end_position,
-                                unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
-                                unsigned int *p_total_component_count = nullptr)
+#ifndef HB_OPTIMIZE_SIZE
+HB_ALWAYS_INLINE
+#endif
+static bool match_input (hb_ot_apply_context_t *c,
+                         unsigned int count, /* Including the first glyph (not matched) */
+                         const HBUINT input[], /* Array of input values--start with second glyph */
+                         match_func_t match_func,
+                         const void *match_data,
+                         unsigned int *end_position,
+                         unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
+                         unsigned int *p_total_component_count = nullptr)
 {
   TRACE_APPLY (nullptr);
 
@@ -1212,7 +1265,7 @@
   hb_buffer_t *buffer = c->buffer;
 
   hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-  skippy_iter.reset (buffer->idx, count - 1);
+  skippy_iter.reset (buffer->idx);
   skippy_iter.set_match_func (match_func, match_data);
   skippy_iter.set_glyph_data (input);
 
@@ -1241,7 +1294,6 @@
    */
 
   unsigned int total_component_count = 0;
-  total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
 
   unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
   unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
@@ -1252,7 +1304,6 @@
     LIGBASE_MAY_SKIP
   } ligbase = LIGBASE_NOT_CHECKED;
 
-  match_positions[0] = buffer->idx;
   for (unsigned int i = 1; i < count; i++)
   {
     unsigned unsafe_to;
@@ -1317,7 +1368,12 @@
   *end_position = skippy_iter.idx + 1;
 
   if (p_total_component_count)
+  {
+    total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
     *p_total_component_count = total_component_count;
+  }
+
+  match_positions[0] = buffer->idx;
 
   return_trace (true);
 }
@@ -1436,17 +1492,20 @@
 }
 
 template 
-static inline bool match_backtrack (hb_ot_apply_context_t *c,
-                                    unsigned int count,
-                                    const HBUINT backtrack[],
-                                    match_func_t match_func,
-                                    const void *match_data,
-                                    unsigned int *match_start)
+#ifndef HB_OPTIMIZE_SIZE
+HB_ALWAYS_INLINE
+#endif
+static bool match_backtrack (hb_ot_apply_context_t *c,
+                             unsigned int count,
+                             const HBUINT backtrack[],
+                             match_func_t match_func,
+                             const void *match_data,
+                             unsigned int *match_start)
 {
   TRACE_APPLY (nullptr);
 
   hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
-  skippy_iter.reset (c->buffer->backtrack_len (), count);
+  skippy_iter.reset (c->buffer->backtrack_len ());
   skippy_iter.set_match_func (match_func, match_data);
   skippy_iter.set_glyph_data (backtrack);
 
@@ -1465,18 +1524,21 @@
 }
 
 template 
-static inline bool match_lookahead (hb_ot_apply_context_t *c,
-                                    unsigned int count,
-                                    const HBUINT lookahead[],
-                                    match_func_t match_func,
-                                    const void *match_data,
-                                    unsigned int start_index,
-                                    unsigned int *end_index)
+#ifndef HB_OPTIMIZE_SIZE
+HB_ALWAYS_INLINE
+#endif
+static bool match_lookahead (hb_ot_apply_context_t *c,
+                             unsigned int count,
+                             const HBUINT lookahead[],
+                             match_func_t match_func,
+                             const void *match_data,
+                             unsigned int start_index,
+                             unsigned int *end_index)
 {
   TRACE_APPLY (nullptr);
 
   hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
-  skippy_iter.reset (start_index - 1, count);
+  skippy_iter.reset (start_index - 1);
   skippy_iter.set_match_func (match_func, match_data);
   skippy_iter.set_glyph_data (lookahead);
 
@@ -1595,10 +1657,13 @@
     }
 
     covered_seq_indicies.add (seqIndex);
+    hb_set_t *cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs))
+      return;
     if (has_pos_glyphs) {
-      c->push_cur_active_glyphs () = std::move (pos_glyphs);
+      *cur_active_glyphs = std::move (pos_glyphs);
     } else {
-      c->push_cur_active_glyphs ().set (*c->glyphs);
+      *cur_active_glyphs = *c->glyphs;
     }
 
     unsigned endIndex = inputCount;
@@ -1848,12 +1913,13 @@
 }
 
 template 
-static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
-                                         unsigned int inputCount, /* Including the first glyph (not matched) */
-                                         const HBUINT input[], /* Array of input values--start with second glyph */
-                                         unsigned int lookupCount,
-                                         const LookupRecord lookupRecord[],
-                                         const ContextApplyLookupContext &lookup_context)
+HB_ALWAYS_INLINE
+static bool context_apply_lookup (hb_ot_apply_context_t *c,
+                                  unsigned int inputCount, /* Including the first glyph (not matched) */
+                                  const HBUINT input[], /* Array of input values--start with second glyph */
+                                  unsigned int lookupCount,
+                                  const LookupRecord lookupRecord[],
+                                  const ContextApplyLookupContext &lookup_context)
 {
   unsigned match_end = 0;
   unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
@@ -1879,6 +1945,9 @@
 template 
 struct Rule
 {
+  template 
+  friend struct RuleSet;
+
   bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const
   {
     return context_intersects (glyphs,
@@ -1981,8 +2050,7 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (inputCount.sanitize (c) &&
-                  lookupCount.sanitize (c) &&
+    return_trace (c->check_struct (this) &&
                   c->check_range (inputZ.arrayZ,
                                   inputZ.item_size * (inputCount ? inputCount - 1 : 0) +
                                   LookupRecord::static_size * lookupCount));
@@ -2066,13 +2134,105 @@
               const ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    return_trace (
-    + hb_iter (rule)
-    | hb_map (hb_add (this))
-    | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
-    | hb_any
-    )
-    ;
+
+    unsigned num_rules = rule.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+    if (HB_OPTIMIZE_SIZE_VAL || num_rules <= 4)
+#endif
+    {
+    slow:
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+
+    /* This version is optimized for speed by matching the first & second
+     * components of the rule here, instead of calling into the matching code.
+     *
+     * Replicated from LigatureSet::apply(). */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset (c->buffer->idx);
+    skippy_iter.set_match_func (match_always, nullptr);
+    skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+    unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0;
+    hb_glyph_info_t *first = nullptr, *second = nullptr;
+    bool matched = skippy_iter.next ();
+    if (likely (matched))
+    {
+      first = &c->buffer->info[skippy_iter.idx];
+      unsafe_to = skippy_iter.idx + 1;
+
+      if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+      {
+        /* Can't use the fast path if eg. the next char is a default-ignorable
+         * or other skippable. */
+        goto slow;
+      }
+    }
+    else
+    {
+      /* Failed to match a next glyph. Only try applying rules that have
+       * no further input. */
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_filter ([&] (const Rule &_) { return _.inputCount <= 1; })
+      | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+    matched = skippy_iter.next ();
+    if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])))
+    {
+      second = &c->buffer->info[skippy_iter.idx];
+      unsafe_to2 = skippy_iter.idx + 1;
+    }
+
+    auto match_input = lookup_context.funcs.match;
+    auto *input_data = lookup_context.match_data;
+    for (unsigned int i = 0; i < num_rules; i++)
+    {
+      const auto &r = this+rule.arrayZ[i];
+
+      const auto &input = r.inputZ;
+
+      if (r.inputCount <= 1 ||
+          (!match_input ||
+           match_input (*first, input.arrayZ[0], input_data)))
+      {
+        if (!second ||
+            (r.inputCount <= 2 ||
+             (!match_input ||
+              match_input (*second, input.arrayZ[1], input_data)))
+           )
+        {
+          if (r.apply (c, lookup_context))
+          {
+            if (unsafe_to != (unsigned) -1)
+              c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+            return_trace (true);
+          }
+        }
+        else
+          unsafe_to = unsafe_to2;
+      }
+      else
+      {
+        if (unsafe_to == (unsigned) -1)
+          unsafe_to = unsafe_to1;
+      }
+    }
+    if (likely (unsafe_to != (unsigned) -1))
+      c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+
+    return_trace (false);
   }
 
   bool subset (hb_subset_context_t *c,
@@ -2148,8 +2308,9 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
-    get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs);
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
+    get_coverage ().intersect_set (c->previous_parent_active_glyphs (), *cur_active_glyphs);
 
     struct ContextClosureLookupContext lookup_context = {
       {intersects_glyph, intersected_glyph},
@@ -2318,9 +2479,10 @@
     if (!(this+coverage).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
+                                   *cur_active_glyphs);
 
     const ClassDef &class_def = this+classDef;
 
@@ -2431,7 +2593,9 @@
     }
   }
 
-  bool apply (hb_ot_apply_context_t *c, bool cached = false) const
+  bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+  bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
+  bool _apply (hb_ot_apply_context_t *c, bool cached) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -2447,11 +2611,7 @@
     if (cached && c->buffer->cur().syllable() < 255)
       index = c->buffer->cur().syllable ();
     else
-    {
       index = class_def.get_class (c->buffer->cur().codepoint);
-      if (cached && index < 255)
-        c->buffer->cur().syllable() = index;
-    }
     const RuleSet &rule_set = this+ruleSet[index];
     return_trace (rule_set.apply (c, lookup_context));
   }
@@ -2561,10 +2721,10 @@
     if (!(this+coverageZ[0]).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
-
+                                   *cur_active_glyphs);
 
     const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount));
     struct ContextClosureLookupContext lookup_context = {
@@ -2665,14 +2825,14 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!c->check_struct (this)) return_trace (false);
+    if (unlikely (!c->check_struct (this))) return_trace (false);
     unsigned int count = glyphCount;
-    if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
-    if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false);
+    if (unlikely (!count)) return_trace (false); /* We want to access coverageZ[0] freely. */
+    if (unlikely (!c->check_array (coverageZ.arrayZ, count))) return_trace (false);
     for (unsigned int i = 0; i < count; i++)
-      if (!coverageZ[i].sanitize (c, this)) return_trace (false);
+      if (unlikely (!coverageZ[i].sanitize (c, this))) return_trace (false);
     const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount));
-    return_trace (c->check_array (lookupRecord, lookupCount));
+    return_trace (likely (c->check_array (lookupRecord, lookupCount)));
   }
 
   protected:
@@ -2845,16 +3005,17 @@
 }
 
 template 
-static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
-                                               unsigned int backtrackCount,
-                                               const HBUINT backtrack[],
-                                               unsigned int inputCount, /* Including the first glyph (not matched) */
-                                               const HBUINT input[], /* Array of input values--start with second glyph */
-                                               unsigned int lookaheadCount,
-                                               const HBUINT lookahead[],
-                                               unsigned int lookupCount,
-                                               const LookupRecord lookupRecord[],
-                                               const ChainContextApplyLookupContext &lookup_context)
+HB_ALWAYS_INLINE
+static bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
+                                        unsigned int backtrackCount,
+                                        const HBUINT backtrack[],
+                                        unsigned int inputCount, /* Including the first glyph (not matched) */
+                                        const HBUINT input[], /* Array of input values--start with second glyph */
+                                        unsigned int lookaheadCount,
+                                        const HBUINT lookahead[],
+                                        unsigned int lookupCount,
+                                        const LookupRecord lookupRecord[],
+                                        const ChainContextApplyLookupContext &lookup_context)
 {
   unsigned end_index = c->buffer->idx;
   unsigned match_end = 0;
@@ -2893,6 +3054,9 @@
 template 
 struct ChainRule
 {
+  template 
+  friend struct ChainRuleSet;
+
   bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
   {
     const auto &input = StructAfter (backtrack);
@@ -2992,8 +3156,6 @@
                   const hb_map_t *lookahead_map = nullptr) const
   {
     TRACE_SERIALIZE (this);
-    auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
 
     const hb_map_t *mapping = backtrack_map;
     serialize_array (c, backtrack.len, + backtrack.iter ()
@@ -3055,13 +3217,14 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!backtrack.sanitize (c)) return_trace (false);
+    /* Hyper-optimized sanitized because this is really hot. */
+    if (unlikely (!backtrack.len.sanitize (c))) return_trace (false);
     const auto &input = StructAfter (backtrack);
-    if (!input.sanitize (c)) return_trace (false);
+    if (unlikely (!input.lenP1.sanitize (c))) return_trace (false);
     const auto &lookahead = StructAfter (input);
-    if (!lookahead.sanitize (c)) return_trace (false);
+    if (unlikely (!lookahead.len.sanitize (c))) return_trace (false);
     const auto &lookup = StructAfter (lookahead);
-    return_trace (lookup.sanitize (c));
+    return_trace (likely (lookup.sanitize (c)));
   }
 
   protected:
@@ -3069,7 +3232,7 @@
                 backtrack;              /* Array of backtracking values
                                          * (to be matched before the input
                                          * sequence) */
-  HeadlessArrayOf
+  HeadlessArray16Of
                 inputX;                 /* Array of input values (start with
                                          * second glyph) */
   Array16Of
@@ -3142,13 +3305,119 @@
               const ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    return_trace (
-    + hb_iter (rule)
-    | hb_map (hb_add (this))
-    | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
-    | hb_any
-    )
-    ;
+
+    unsigned num_rules = rule.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+    if (HB_OPTIMIZE_SIZE_VAL || num_rules <= 4)
+#endif
+    {
+    slow:
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+
+    /* This version is optimized for speed by matching the first & second
+     * components of the rule here, instead of calling into the matching code.
+     *
+     * Replicated from LigatureSet::apply(). */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset (c->buffer->idx);
+    skippy_iter.set_match_func (match_always, nullptr);
+    skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+    unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0;
+    hb_glyph_info_t *first = nullptr, *second = nullptr;
+    bool matched = skippy_iter.next ();
+    if (likely (matched))
+    {
+      first = &c->buffer->info[skippy_iter.idx];
+      unsafe_to1 = skippy_iter.idx + 1;
+
+      if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+      {
+        /* Can't use the fast path if eg. the next char is a default-ignorable
+         * or other skippable. */
+        goto slow;
+      }
+    }
+    else
+    {
+      /* Failed to match a next glyph. Only try applying rules that have
+       * no further input and lookahead. */
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_filter ([&] (const ChainRule &_)
+                   {
+                     const auto &input = StructAfter (_.backtrack);
+                     const auto &lookahead = StructAfter (input);
+                     return input.lenP1 <= 1 && lookahead.len == 0;
+                   })
+      | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+    matched = skippy_iter.next ();
+    if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])))
+     {
+      second = &c->buffer->info[skippy_iter.idx];
+      unsafe_to2 = skippy_iter.idx + 1;
+     }
+
+    auto match_input = lookup_context.funcs.match[1];
+    auto match_lookahead = lookup_context.funcs.match[2];
+    auto *input_data = lookup_context.match_data[1];
+    auto *lookahead_data = lookup_context.match_data[2];
+    for (unsigned int i = 0; i < num_rules; i++)
+    {
+      const auto &r = this+rule.arrayZ[i];
+
+      const auto &input = StructAfter (r.backtrack);
+      const auto &lookahead = StructAfter (input);
+
+      unsigned lenP1 = hb_max ((unsigned) input.lenP1, 1u);
+      if (lenP1 > 1 ?
+           (!match_input ||
+            match_input (*first, input.arrayZ[0], input_data))
+          :
+           (!lookahead.len || !match_lookahead ||
+            match_lookahead (*first, lookahead.arrayZ[0], lookahead_data)))
+      {
+        if (!second ||
+            (lenP1 > 2 ?
+             (!match_input ||
+              match_input (*second, input.arrayZ[1], input_data))
+             :
+             (lookahead.len <= 2 - lenP1 || !match_lookahead ||
+              match_lookahead (*second, lookahead.arrayZ[2 - lenP1], lookahead_data))))
+        {
+          if (r.apply (c, lookup_context))
+          {
+            if (unsafe_to != (unsigned) -1)
+              c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+            return_trace (true);
+          }
+        }
+        else
+          unsafe_to = unsafe_to2;
+      }
+      else
+      {
+        if (unsafe_to == (unsigned) -1)
+          unsafe_to = unsafe_to1;
+      }
+    }
+    if (likely (unsafe_to != (unsigned) -1))
+      c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+
+    return_trace (false);
   }
 
   bool subset (hb_subset_context_t *c,
@@ -3229,9 +3498,10 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
+                                   *cur_active_glyphs);
 
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_glyph, intersected_glyph},
@@ -3401,10 +3671,10 @@
     if (!(this+coverage).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
-
+                                   *cur_active_glyphs);
 
     const ClassDef &backtrack_class_def = this+backtrackClassDef;
     const ClassDef &input_class_def = this+inputClassDef;
@@ -3534,7 +3804,9 @@
     }
   }
 
-  bool apply (hb_ot_apply_context_t *c, bool cached = false) const
+  bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+  bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
+  bool _apply (hb_ot_apply_context_t *c, bool cached) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -3544,26 +3816,22 @@
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
 
-    /* For ChainContextFormat2_5 we cache the LookaheadClassDef instead of InputClassDef.
-     * The reason is that most heavy fonts want to identify a glyph in context and apply
-     * a lookup to it. In this scenario, the length of the input sequence is one, whereas
-     * the lookahead / backtrack are typically longer.  The one glyph in input sequence is
-     * looked-up below and no input glyph is looked up in individual rules, whereas the
-     * lookahead and backtrack glyphs are tried.  Since we match lookahead before backtrack,
-     * we should cache lookahead.  This decisions showed a 20% improvement in shaping of
-     * the Gulzar font.
-     */
-
+    /* match_class_caches1 is slightly faster. Use it for lookahead,
+     * which is typically longer. */
     struct ChainContextApplyLookupContext lookup_context = {
-      {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached : match_class,
-        cached && &input_class_def == &lookahead_class_def ? match_class_cached : match_class,
-        cached ? match_class_cached : match_class}},
+      {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached1 : match_class,
+        cached ? match_class_cached2 : match_class,
+        cached ? match_class_cached1 : match_class}},
       {&backtrack_class_def,
        &input_class_def,
        &lookahead_class_def}
     };
 
-    index = input_class_def.get_class (c->buffer->cur().codepoint);
+    // Note: Corresponds to match_class_cached2
+    if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15)
+      index = (c->buffer->cur().syllable () & 0xF0) >> 4;
+    else
+      index = input_class_def.get_class (c->buffer->cur().codepoint);
     const ChainRuleSet &rule_set = this+ruleSet[index];
     return_trace (rule_set.apply (c, lookup_context));
   }
@@ -3703,10 +3971,11 @@
     if (!(this+input[0]).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs))
+      return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
-
+                                   *cur_active_glyphs);
 
     const auto &lookahead = StructAfter (input);
     const auto &lookup = StructAfter (lookahead);
@@ -3825,8 +4094,6 @@
   {
     TRACE_SUBSET (this);
 
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
 
     if (!serialize_coverage_offsets (c, backtrack.iter (), this))
@@ -3853,14 +4120,14 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!backtrack.sanitize (c, this)) return_trace (false);
+    if (unlikely (!backtrack.sanitize (c, this))) return_trace (false);
     const auto &input = StructAfter (backtrack);
-    if (!input.sanitize (c, this)) return_trace (false);
-    if (!input.len) return_trace (false); /* To be consistent with Context. */
+    if (unlikely (!input.sanitize (c, this))) return_trace (false);
+    if (unlikely (!input.len)) return_trace (false); /* To be consistent with Context. */
     const auto &lookahead = StructAfter (input);
-    if (!lookahead.sanitize (c, this)) return_trace (false);
+    if (unlikely (!lookahead.sanitize (c, this))) return_trace (false);
     const auto &lookup = StructAfter (lookahead);
-    return_trace (lookup.sanitize (c));
+    return_trace (likely (lookup.sanitize (c)));
   }
 
   protected:
@@ -3950,7 +4217,7 @@
     TRACE_SUBSET (this);
 
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     out->format = format;
     out->extensionLookupType = extensionLookupType;
@@ -4068,6 +4335,9 @@
   bool may_have (hb_codepoint_t g) const
   { return digest.may_have (g); }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const
   {
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
@@ -4479,7 +4749,10 @@
   {
     accelerator_t (hb_face_t *face)
     {
-      this->table = hb_sanitize_context_t ().reference_table (face);
+      hb_sanitize_context_t sc;
+      sc.lazy_some_gpos = true;
+      this->table = sc.reference_table (face);
+
       if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
       {
         hb_blob_destroy (this->table.get_blob ());
@@ -4504,6 +4777,8 @@
       this->table.destroy ();
     }
 
+    hb_blob_t *get_blob () const { return table.get_blob (); }
+
     hb_ot_layout_lookup_accelerator_t *get_accel (unsigned lookup_index) const
     {
       if (unlikely (lookup_index >= lookup_count)) return nullptr;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc	2024-01-16 16:19:00.000000000 +0000
@@ -64,8 +64,8 @@
  * @include: hb-ot.h
  *
  * Functions for querying OpenType Layout features in the font face.
- * See the OpenType
- * specification for details.
+ * See the [OpenType specification](http://www.microsoft.com/typography/otspec/)
+ * for details.
  **/
 
 
@@ -257,12 +257,13 @@
 {
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
-  const OT::GDEF &gdef = *font->face->table.GDEF->table;
+  const auto &gdef = *font->face->table.GDEF;
   unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
   {
-    _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
-    _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+    _hb_glyph_info_set_glyph_props (&info[i], gdef.get_glyph_props (info[i].codepoint));
+    _hb_glyph_info_clear_lig_props (&info[i]);
   }
 }
 
@@ -1240,7 +1241,7 @@
  *   terminated by %HB_TAG_NONE
  * @features: (nullable) (array zero-terminated=1): The array of features to collect,
  *   terminated by %HB_TAG_NONE
- * @feature_indexes: (out): The array of feature indexes found for the query
+ * @feature_indexes: (out): The set of feature indexes found for the query
  *
  * Fetches a list of all feature indexes in the specified face's GSUB table
  * or GPOS table, underneath the specified scripts, languages, and features.
@@ -1281,6 +1282,49 @@
   }
 }
 
+/**
+ * hb_ot_layout_collect_features_map:
+ * @face: #hb_face_t to work upon
+ * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @feature_map: (out): The map of feature tag to feature index.
+ *
+ * Fetches the mapping from feature tags to feature indexes for
+ * the specified script and language.
+ *
+ * Since: 8.1.0
+ **/
+void
+hb_ot_layout_collect_features_map (hb_face_t      *face,
+                                   hb_tag_t        table_tag,
+                                   unsigned        script_index,
+                                   unsigned        language_index,
+                                   hb_map_t       *feature_map /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+  unsigned int count = l.get_feature_indexes (0, nullptr, nullptr);
+  feature_map->alloc (count);
+
+  /* Loop in reverse, such that earlier entries win. That emulates
+   * a linear search, which seems to be what other implementations do.
+   * We found that with arialuni_t.ttf, the "ur" language system has
+   * duplicate features, and the earlier ones work but not later ones.
+   */
+  for (unsigned int i = count; i; i--)
+  {
+    unsigned feature_index = 0;
+    unsigned feature_count = 1;
+    l.get_feature_indexes (i - 1, &feature_count, &feature_index);
+    if (!feature_count)
+      break;
+    hb_tag_t feature_tag = g.get_feature_tag (feature_index);
+    feature_map->set (feature_tag, feature_index);
+  }
+}
+
 
 /**
  * hb_ot_layout_collect_lookups:
@@ -1315,8 +1359,7 @@
   hb_set_t feature_indexes;
   hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes);
 
-  for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID;
-       hb_set_next (&feature_indexes, &feature_index);)
+  for (auto feature_index : feature_indexes)
     g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
 
   g.feature_variation_collect_lookups (&feature_indexes, nullptr, lookup_indexes);
@@ -1569,7 +1612,7 @@
     glyphs_length = glyphs->get_population ();
     if (lookups)
     {
-      for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
+      for (auto lookup_index : *lookups)
         gsub.get_lookup (lookup_index).closure (&c, lookup_index);
     }
     else
@@ -1895,7 +1938,7 @@
     if (accel.digest.may_have (buffer->cur().codepoint) &&
         (buffer->cur().mask & c->lookup_mask) &&
         c->check_glyph_property (&buffer->cur(), c->lookup_props))
-     ret |= accel.apply (c, subtable_count, false);
+      ret |= accel.apply (c, subtable_count, false);
 
     /* The reverse lookup doesn't "advance" cursor (for good reason). */
     buffer->idx--;
@@ -1952,7 +1995,7 @@
 {
   const unsigned int table_index = proxy.table_index;
   unsigned int i = 0;
-  OT::hb_ot_apply_context_t c (table_index, font, buffer);
+  OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob ());
   c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func);
 
   for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++)
@@ -1977,11 +2020,12 @@
       if (accel->digest.may_have (c.digest))
       {
         c.set_lookup_index (lookup_index);
-        c.set_lookup_mask (lookup.mask);
-        c.set_auto_zwj (lookup.auto_zwj);
-        c.set_auto_zwnj (lookup.auto_zwnj);
+        c.set_lookup_mask (lookup.mask, false);
+        c.set_auto_zwj (lookup.auto_zwj, false);
+        c.set_auto_zwnj (lookup.auto_zwnj, false);
         c.set_random (lookup.random);
-        c.set_per_syllable (lookup.per_syllable);
+        c.set_per_syllable (lookup.per_syllable, false);
+        /* apply_string's set_lookup_props initializes the iterators. */
 
         apply_string (&c,
                              proxy.accel.table->get_lookup (lookup_index),
@@ -2009,20 +2053,20 @@
 {
   GSUBProxy proxy (font->face);
   if (buffer->messaging () &&
-      !buffer->message (font, "start table GSUB")) return;
+      !buffer->message (font, "start table GSUB script tag '%c%c%c%c'", HB_UNTAG (chosen_script[0]))) return;
   apply (proxy, plan, font, buffer);
   if (buffer->messaging ())
-    (void) buffer->message (font, "end table GSUB");
+    (void) buffer->message (font, "end table GSUB script tag '%c%c%c%c'", HB_UNTAG (chosen_script[0]));
 }
 
 void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
 {
   GPOSProxy proxy (font->face);
   if (buffer->messaging () &&
-      !buffer->message (font, "start table GPOS")) return;
+      !buffer->message (font, "start table GPOS script tag '%c%c%c%c'", HB_UNTAG (chosen_script[1]))) return;
   apply (proxy, plan, font, buffer);
   if (buffer->messaging ())
-    (void) buffer->message (font, "end table GPOS");
+    (void) buffer->message (font, "end table GPOS script tag '%c%c%c%c'", HB_UNTAG (chosen_script[1]));
 }
 
 void
@@ -2034,6 +2078,112 @@
 }
 
 #ifndef HB_NO_BASE
+
+static void
+choose_base_tags (hb_script_t    script,
+                  hb_language_t  language,
+                  hb_tag_t      *script_tag,
+                  hb_tag_t      *language_tag)
+{
+  hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT];
+  unsigned script_count = ARRAY_LENGTH (script_tags);
+
+  hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
+  unsigned language_count = ARRAY_LENGTH (language_tags);
+
+  hb_ot_tags_from_script_and_language (script, language,
+                                       &script_count, script_tags,
+                                       &language_count, language_tags);
+
+  *script_tag = script_count ? script_tags[script_count - 1] : HB_OT_TAG_DEFAULT_SCRIPT;
+  *language_tag = language_count ? language_tags[language_count - 1] : HB_OT_TAG_DEFAULT_LANGUAGE;
+}
+
+/**
+ * hb_ot_layout_get_font_extents:
+ * @font: a font
+ * @direction: text direction.
+ * @script_tag:  script tag.
+ * @language_tag: language tag.
+ * @extents: (out) (nullable): font extents if found.
+ *
+ * Fetches script/language-specific font extents.  These values are
+ * looked up in the `BASE` table's `MinMax` records.
+ *
+ * If no such extents are found, the default extents for the font are
+ * fetched. As such, the return value of this function can for the
+ * most part be ignored.  Note that the per-script/language extents
+ * do not have a line-gap value, and the line-gap is set to zero in
+ * that case.
+ *
+ * Return value: `true` if found script/language-specific font extents.
+ *
+ * Since: 8.0.0
+ **/
+hb_bool_t
+hb_ot_layout_get_font_extents (hb_font_t         *font,
+                               hb_direction_t     direction,
+                               hb_tag_t           script_tag,
+                               hb_tag_t           language_tag,
+                               hb_font_extents_t *extents)
+{
+  hb_position_t min, max;
+  if (font->face->table.BASE->get_min_max (font, direction, script_tag, language_tag, HB_TAG_NONE,
+                                           &min, &max))
+  {
+    if (extents)
+    {
+      extents->ascender  = max;
+      extents->descender = min;
+      extents->line_gap  = 0;
+    }
+    return true;
+  }
+
+  hb_font_get_extents_for_direction (font, direction, extents);
+  return false;
+}
+
+/**
+ * hb_ot_layout_get_font_extents2:
+ * @font: a font
+ * @direction: text direction.
+ * @script:  script.
+ * @language: (nullable): language.
+ * @extents: (out) (nullable): font extents if found.
+ *
+ * Fetches script/language-specific font extents.  These values are
+ * looked up in the `BASE` table's `MinMax` records.
+ *
+ * If no such extents are found, the default extents for the font are
+ * fetched. As such, the return value of this function can for the
+ * most part be ignored.  Note that the per-script/language extents
+ * do not have a line-gap value, and the line-gap is set to zero in
+ * that case.
+ *
+ * This function is like hb_ot_layout_get_font_extents() but takes
+ * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t.
+ *
+ * Return value: `true` if found script/language-specific font extents.
+ *
+ * Since: 8.0.0
+ **/
+hb_bool_t
+hb_ot_layout_get_font_extents2 (hb_font_t         *font,
+                                hb_direction_t     direction,
+                                hb_script_t        script,
+                                hb_language_t      language,
+                                hb_font_extents_t *extents)
+{
+  hb_tag_t script_tag, language_tag;
+  choose_base_tags (script, language, &script_tag, &language_tag);
+  return hb_ot_layout_get_font_extents (font,
+                                        direction,
+                                        script_tag,
+                                        language_tag,
+                                        extents);
+}
+
 /**
  * hb_ot_layout_get_horizontal_baseline_tag_for_script:
  * @script: a script tag.
@@ -2132,6 +2282,42 @@
 }
 
 /**
+ * hb_ot_layout_get_baseline2:
+ * @font: a font
+ * @baseline_tag: a baseline tag
+ * @direction: text direction.
+ * @script:  script.
+ * @language: (nullable): language, currently unused.
+ * @coord: (out) (nullable): baseline value if found.
+ *
+ * Fetches a baseline value from the face.
+ *
+ * This function is like hb_ot_layout_get_baseline() but takes
+ * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t.
+ *
+ * Return value: `true` if found baseline value in the font.
+ *
+ * Since: 8.0.0
+ **/
+hb_bool_t
+hb_ot_layout_get_baseline2 (hb_font_t                   *font,
+                            hb_ot_layout_baseline_tag_t  baseline_tag,
+                            hb_direction_t               direction,
+                            hb_script_t                  script,
+                            hb_language_t                language,
+                            hb_position_t               *coord        /* OUT.  May be NULL. */)
+{
+  hb_tag_t script_tag, language_tag;
+  choose_base_tags (script, language, &script_tag, &language_tag);
+  return hb_ot_layout_get_baseline (font,
+                                    baseline_tag,
+                                    direction,
+                                    script_tag,
+                                    language_tag,
+                                    coord);
+}
+
+/**
  * hb_ot_layout_get_baseline_with_fallback:
  * @font: a font
  * @baseline_tag: a baseline tag
@@ -2353,6 +2539,41 @@
   }
 }
 
+/**
+ * hb_ot_layout_get_baseline_with_fallback2:
+ * @font: a font
+ * @baseline_tag: a baseline tag
+ * @direction: text direction.
+ * @script:  script.
+ * @language: (nullable): language, currently unused.
+ * @coord: (out): baseline value if found.
+ *
+ * Fetches a baseline value from the face, and synthesizes
+ * it if the font does not have it.
+ *
+ * This function is like hb_ot_layout_get_baseline_with_fallback() but takes
+ * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t.
+ *
+ * Since: 8.0.0
+ **/
+void
+hb_ot_layout_get_baseline_with_fallback2 (hb_font_t                   *font,
+                                          hb_ot_layout_baseline_tag_t  baseline_tag,
+                                          hb_direction_t               direction,
+                                          hb_script_t                  script,
+                                          hb_language_t                language,
+                                          hb_position_t               *coord        /* OUT */)
+{
+  hb_tag_t script_tag, language_tag;
+  choose_base_tags (script, language, &script_tag, &language_tag);
+  hb_ot_layout_get_baseline_with_fallback (font,
+                                           baseline_tag,
+                                           direction,
+                                           script_tag,
+                                           language_tag,
+                                           coord);
+}
+
 #endif
 
 
@@ -2449,9 +2670,10 @@
                                        hb_codepoint_t  glyph)
 {
   const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index);
+  hb_blob_t *blob = font->face->table.GPOS->get_blob ();
   hb_glyph_position_t pos = {0};
   hb_position_single_dispatch_t c;
-  lookup.dispatch (&c, font, direction, glyph, pos);
+  lookup.dispatch (&c, font, blob, direction, glyph, pos);
   hb_position_t ret = 0;
   switch (direction)
   {
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h	2024-01-16 16:19:00.000000000 +0000
@@ -325,6 +325,13 @@
                                hb_set_t       *feature_indexes /* OUT */);
 
 HB_EXTERN void
+hb_ot_layout_collect_features_map (hb_face_t      *face,
+                                   hb_tag_t        table_tag,
+                                   unsigned        script_index,
+                                   unsigned        language_index,
+                                   hb_map_t       *feature_map /* OUT */);
+
+HB_EXTERN void
 hb_ot_layout_collect_lookups (hb_face_t      *face,
                               hb_tag_t        table_tag,
                               const hb_tag_t *scripts,
@@ -447,6 +454,20 @@
  * BASE
  */
 
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_font_extents (hb_font_t         *font,
+                               hb_direction_t     direction,
+                               hb_tag_t           script_tag,
+                               hb_tag_t           language_tag,
+                               hb_font_extents_t *extents);
+
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_font_extents2 (hb_font_t         *font,
+                                hb_direction_t     direction,
+                                hb_script_t        script,
+                                hb_language_t      language,
+                                hb_font_extents_t *extents);
+
 /**
  * hb_ot_layout_baseline_tag_t:
  * @HB_OT_LAYOUT_BASELINE_TAG_ROMAN: The baseline used by alphabetic scripts such as Latin, Cyrillic and Greek.
@@ -499,6 +520,14 @@
                            hb_tag_t                     language_tag,
                            hb_position_t               *coord        /* OUT.  May be NULL. */);
 
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_baseline2 (hb_font_t                   *font,
+                            hb_ot_layout_baseline_tag_t  baseline_tag,
+                            hb_direction_t               direction,
+                            hb_script_t                  script,
+                            hb_language_t                language,
+                            hb_position_t               *coord        /* OUT.  May be NULL. */);
+
 HB_EXTERN void
 hb_ot_layout_get_baseline_with_fallback (hb_font_t                   *font,
                                          hb_ot_layout_baseline_tag_t  baseline_tag,
@@ -507,6 +536,14 @@
                                          hb_tag_t                     language_tag,
                                          hb_position_t               *coord        /* OUT */);
 
+HB_EXTERN void
+hb_ot_layout_get_baseline_with_fallback2 (hb_font_t                   *font,
+                                          hb_ot_layout_baseline_tag_t  baseline_tag,
+                                          hb_direction_t               direction,
+                                          hb_script_t                  script,
+                                          hb_language_t                language,
+                                          hb_position_t               *coord        /* OUT */);
+
 HB_END_DECLS
 
 #endif /* HB_OT_LAYOUT_H */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh	2024-01-16 16:19:00.000000000 +0000
@@ -448,7 +448,7 @@
 static inline bool
 _hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
 {
-  return !!(info->lig_props() & IS_LIG_BASE);
+  return info->lig_props() & IS_LIG_BASE;
 }
 
 static inline unsigned int
@@ -496,37 +496,37 @@
 static inline bool
 _hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
 }
 
 static inline bool
 _hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
 }
 
 static inline bool
 _hb_glyph_info_is_mark (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK;
 }
 
 static inline bool
 _hb_glyph_info_substituted (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
 }
 
 static inline bool
 _hb_glyph_info_ligated (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
 }
 
 static inline bool
 _hb_glyph_info_multiplied (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
 }
 
 static inline bool
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc	2024-01-16 16:19:00.000000000 +0000
@@ -213,7 +213,8 @@
   /* Sort features and merge duplicates */
   if (feature_infos.length)
   {
-    feature_infos.qsort ();
+    if (!is_simple)
+      feature_infos.qsort ();
     auto *f = feature_infos.arrayZ;
     unsigned int j = 0;
     unsigned count = feature_infos.length;
@@ -238,6 +239,13 @@
     feature_infos.shrink (j + 1);
   }
 
+  hb_map_t feature_indices[2];
+  for (unsigned int table_index = 0; table_index < 2; table_index++)
+    hb_ot_layout_collect_features_map (face,
+                                       table_tags[table_index],
+                                       script_index[table_index],
+                                       language_index[table_index],
+                                       &feature_indices[table_index]);
 
   /* Allocate bits now */
   static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
@@ -260,7 +268,6 @@
     if (!info->max_value || next_bit + bits_needed >= global_bit_shift)
       continue; /* Feature disabled, or not enough bits. */
 
-
     bool found = false;
     unsigned int feature_index[2];
     for (unsigned int table_index = 0; table_index < 2; table_index++)
@@ -268,12 +275,14 @@
       if (required_feature_tag[table_index] == info->tag)
         required_feature_stage[table_index] = info->stage[table_index];
 
-      found |= (bool) hb_ot_layout_language_find_feature (face,
-                                                          table_tags[table_index],
-                                                          script_index[table_index],
-                                                          language_index[table_index],
-                                                          info->tag,
-                                                          &feature_index[table_index]);
+      hb_codepoint_t *index;
+      if (feature_indices[table_index].has (info->tag, &index))
+      {
+        feature_index[table_index] = *index;
+        found = true;
+      }
+      else
+        feature_index[table_index] = HB_OT_LAYOUT_NO_FEATURE_INDEX;
     }
     if (!found && (info->flags & F_GLOBAL_SEARCH))
     {
@@ -314,7 +323,8 @@
     map->needs_fallback = !found;
   }
   //feature_infos.shrink (0); /* Done with these */
-
+  if (is_simple)
+    m.features.qsort ();
 
   add_gsub_pause (nullptr);
   add_gpos_pause (nullptr);
@@ -350,7 +360,7 @@
       }
 
       /* Sort lookups and merge duplicates */
-      if (last_num_lookups < lookups.length)
+      if (last_num_lookups + 1 < lookups.length)
       {
         lookups.as_array ().sub_array (last_num_lookups, lookups.length - last_num_lookups).qsort ();
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh	2024-01-16 16:19:00.000000000 +0000
@@ -60,6 +60,13 @@
 
     int cmp (const hb_tag_t tag_) const
     { return tag_ < tag ? -1 : tag_ > tag ? 1 : 0; }
+
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
+    {
+      const feature_map_t *a = (const feature_map_t *) pa;
+      const feature_map_t *b = (const feature_map_t *) pb;
+      return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0;
+    }
   };
 
   struct lookup_map_t {
@@ -273,6 +280,7 @@
 
   hb_face_t *face;
   hb_segment_properties_t props;
+  bool is_simple;
 
   hb_tag_t chosen_script[2];
   bool found_script[2];
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -73,7 +73,6 @@
   {
     TRACE_SERIALIZE (this);
     auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
 
     HBINT16 *p = c->allocate_size (HBINT16::static_size * 2);
     if (unlikely (!p)) return_trace (nullptr);
@@ -310,7 +309,6 @@
   {
     TRACE_SERIALIZE (this);
     auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
 
     if (unlikely (!c->embed (heightCount))) return_trace (nullptr);
 
@@ -572,6 +570,7 @@
 
     auto it =
     + hb_iter (this+extendedShapeCoverage)
+    | hb_take (c->plan->source->get_num_glyphs ())
     | hb_filter (glyphset)
     | hb_map_retains_sorting (glyph_map)
     ;
@@ -757,8 +756,6 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
 
     if (!c->serializer->copy (italicsCorrection, this)) return_trace (false);
     if (!c->serializer->copy (partRecords.len)) return_trace (false);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc	2024-01-16 16:19:00.000000000 +0000
@@ -76,7 +76,7 @@
  *
  * However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
  * #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
- * #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, then the return value is
+ * #HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT, then the return value is
  * an integer between 0 and 100 representing that percentage.
  *
  * Return value: the requested constant or zero
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc	2024-01-16 16:19:00.000000000 +0000
@@ -196,7 +196,7 @@
         *position *= mult;
 
         if (font->slant)
-          *position += _hb_roundf (mult * font->slant_xy * rise);
+          *position += roundf (mult * font->slant_xy * rise);
       }
 
       return ret;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -246,24 +246,19 @@
     }
 #endif
 
-    if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t')) &&
-        !c->plan->pinned_at_default)
+    Triple *axis_range;
+    if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t'), &axis_range))
     {
-      float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t'));
-      if (!c->serializer->check_assign (os2_prime->usWeightClass,
-                                        roundf (hb_clamp (weight_class, 1.0f, 1000.0f)),
-                                        HB_SERIALIZE_ERROR_INT_OVERFLOW))
-        return_trace (false);
+      unsigned weight_class = static_cast (roundf (hb_clamp (axis_range->middle, 1.0f, 1000.0f)));
+      if (os2_prime->usWeightClass != weight_class)
+        os2_prime->usWeightClass = weight_class;
     }
 
-    if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h')) &&
-        !c->plan->pinned_at_default)
+    if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h'), &axis_range))
     {
-      float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h'));
-      if (!c->serializer->check_assign (os2_prime->usWidthClass,
-                                        roundf (map_wdth_to_widthclass (width)),
-                                        HB_SERIALIZE_ERROR_INT_OVERFLOW))
-        return_trace (false);
+      unsigned width_class = static_cast (roundf (map_wdth_to_widthclass (axis_range->middle)));
+      if (os2_prime->usWidthClass != width_class)
+        os2_prime->usWidthClass = width_class;
     }
 
     if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
@@ -287,8 +282,7 @@
     /* This block doesn't show up in profiles. If it ever did,
      * we can rewrite it to iterate over OS/2 ranges and use
      * set iteration to check if the range matches. */
-    for (hb_codepoint_t cp = HB_SET_VALUE_INVALID;
-         codepoints->next (&cp);)
+    for (auto cp : *codepoints)
     {
       unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
       if (bit < 128)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh	2024-01-16 16:19:00.000000000 +0000
@@ -79,6 +79,11 @@
   post::accelerator_t _post (c->plan->source);
 
   hb_hashmap_t glyph_name_to_new_index;
+
+  old_new_index_map.alloc (num_glyphs);
+  old_gid_new_index_map.alloc (num_glyphs);
+  glyph_name_to_new_index.alloc (num_glyphs);
+
   for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
   {
     hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
@@ -86,11 +91,12 @@
 
     unsigned new_index;
     const uint32_t *new_index2;
-    if (old_index <= 257) new_index = old_index;
+    if (old_index <= 257)
+      new_index = old_index;
     else if (old_new_index_map.has (old_index, &new_index2))
-    {
       new_index = *new_index2;
-    } else {
+    else
+    {
       hb_bytes_t s = _post.find_glyph_name (old_gid);
       new_index = glyph_name_to_new_index.get (s);
       if (new_index == (unsigned)-1)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -96,8 +96,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    post *post_prime = c->serializer->start_embed ();
-    if (unlikely (!post_prime)) return_trace (false);
+    auto *post_prime = c->serializer->start_embed ();
 
     bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
     if (!serialize (c->serializer, glyph_names))
@@ -114,12 +113,12 @@
     }
 #endif
 
-    if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) &&
-        !c->plan->pinned_at_default)
+    Triple *axis_range;
+    if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t'), &axis_range))
     {
-      float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t'));
-      italic_angle = hb_max (-90.f, hb_min (italic_angle, 90.f));
-      post_prime->italicAngle.set_float (italic_angle);
+      float italic_angle = hb_max (-90.f, hb_min (axis_range->middle, 90.f));
+      if (post_prime->italicAngle.to_float () != italic_angle)
+        post_prime->italicAngle.set_float (italic_angle);
     }
 
     if (glyph_names && version.major == 2)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc	2024-01-16 16:19:00.000000000 +0000
@@ -383,14 +383,15 @@
   if (!all_simple && buffer->message(font, "start reorder"))
   {
     count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
     for (unsigned int i = 0; i < count; i++)
     {
-      if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
+      if (_hb_glyph_info_get_modified_combining_class (&info[i]) == 0)
         continue;
 
       unsigned int end;
       for (end = i + 1; end < count; end++)
-        if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
+        if (_hb_glyph_info_get_modified_combining_class (&info[end]) == 0)
           break;
 
       /* We are going to do a O(n^2).  Only do this if the sequence is short. */
@@ -414,11 +415,13 @@
      * If it did NOT, then make it skippable.
      * https://github.com/harfbuzz/harfbuzz/issues/554
      */
-    for (unsigned int i = 1; i + 1 < buffer->len; i++)
-      if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
-          (info_cc(buffer->info[i+1]) == 0 || info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])))
+    unsigned count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    for (unsigned int i = 1; i + 1 < count; i++)
+      if (info[i].codepoint == 0x034Fu/*CGJ*/ &&
+          (info_cc(info[i+1]) == 0 || info_cc(info[i-1]) <= info_cc(info[i+1])))
       {
-        _hb_glyph_info_unhide (&buffer->info[i]);
+        _hb_glyph_info_unhide (&info[i]);
       }
   }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc	2024-01-16 16:19:00.000000000 +0000
@@ -313,6 +313,8 @@
 {
   hb_ot_map_builder_t *map = &planner->map;
 
+  map->is_simple = true;
+
   map->enable_feature (HB_TAG('r','v','r','n'));
   map->add_gsub_pause (nullptr);
 
@@ -354,7 +356,10 @@
   map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */
 
   if (planner->shaper->collect_features)
+  {
+    map->is_simple = false;
     planner->shaper->collect_features (planner);
+  }
 
   map->enable_feature (HB_TAG ('B','u','z','z')); /* Considered required. */
   map->enable_feature (HB_TAG ('B','U','Z','Z')); /* Considered discretionary. */
@@ -378,6 +383,8 @@
     map->enable_feature (HB_TAG ('v','e','r','t'), F_GLOBAL_SEARCH);
   }
 
+  if (num_user_features)
+    map->is_simple = false;
   for (unsigned int i = 0; i < num_user_features; i++)
   {
     const hb_feature_t *feature = &user_features[i];
@@ -469,9 +476,18 @@
   {
     _hb_glyph_info_set_unicode_props (&info[i], buffer);
 
+    unsigned gen_cat = _hb_glyph_info_get_general_category (&info[i]);
+    if (FLAG_UNSAFE (gen_cat) &
+        (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR)))
+      continue;
+
     /* Marks are already set as continuation by the above line.
      * Handle Emoji_Modifier and ZWJ-continuation. */
-    if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
+    if (unlikely (gen_cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
                   hb_in_range (info[i].codepoint, 0x1F3FBu, 0x1F3FFu)))
     {
       _hb_glyph_info_set_continuation (&info[i]);
@@ -749,6 +765,14 @@
              _hb_glyph_info_get_general_category (&info[end]) ==
              HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
         end++;
+      if (start == i || end == i + 1)
+      {
+        if (start == i)
+          buffer->unsafe_to_concat (start, start + 1);
+        if (end == i + 1)
+          buffer->unsafe_to_concat (end - 1, end);
+        continue;
+      }
 
       buffer->unsafe_to_break (start, end);
 
@@ -1030,7 +1054,7 @@
    * direction is backward we don't shift and it will end up
    * hanging over the next glyph after the final reordering.
    *
-   * Note: If fallback positinoing happens, we don't care about
+   * Note: If fallback positioning happens, we don't care about
    * this as it will be overridden.
    */
   bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh	2024-01-16 16:19:00.000000000 +0000
@@ -368,7 +368,7 @@
                             hb_font_t *font,
                             hb_buffer_t *buffer)
 {
-  OT::hb_ot_apply_context_t c (0, font, buffer);
+  OT::hb_ot_apply_context_t c (0, font, buffer, hb_blob_get_empty ());
   for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
     if (fallback_plan->lookup_array[i]) {
       c.set_lookup_mask (fallback_plan->mask_array[i]);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh	2024-01-16 16:19:00.000000000 +0000
@@ -6,10 +6,10 @@
  *
  * on files with these headers:
  *
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
+ * # ArabicShaping-15.1.0.txt
+ * # Date: 2023-01-05
+ * # Scripts-15.1.0.txt
+ * # Date: 2023-07-28, 16:01:07 GMT
  */
 
 #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -6,10 +6,10 @@
  *
  * on files with these headers:
  *
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
+ * # ArabicShaping-15.1.0.txt
+ * # Date: 2023-01-05
+ * # Blocks-15.1.0.txt
+ * # Date: 2023-07-28, 15:47:20 GMT
  * UnicodeData.txt does not have a header.
  */
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc	2024-01-16 16:19:00.000000000 +0000
@@ -486,8 +486,10 @@
   if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH)))
     return;
 
-  /* The Arabic shaper currently always processes in RTL mode, so we should
-   * stretch / position the stretched pieces to the left / preceding glyphs. */
+  bool rtl = buffer->props.direction == HB_DIRECTION_RTL;
+
+  if (!rtl)
+    buffer->reverse ();
 
   /* We do a two pass implementation:
    * First pass calculates the exact number of extra glyphs we need,
@@ -577,7 +579,10 @@
         ++n_copies;
         hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
         if (excess > 0)
+        {
           extra_repeat_overlap = excess / (n_copies * n_repeating);
+          w_remaining = 0;
+        }
       }
 
       if (step == MEASURE)
@@ -588,7 +593,7 @@
       else
       {
         buffer->unsafe_to_break (context, end);
-        hb_position_t x_offset = 0;
+        hb_position_t x_offset = w_remaining / 2;
         for (unsigned int k = end; k > start; k--)
         {
           hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint);
@@ -599,16 +604,27 @@
 
           DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u",
                      repeat, info[k - 1].codepoint, j);
+          pos[k - 1].x_advance = 0;
           for (unsigned int n = 0; n < repeat; n++)
           {
-            x_offset -= width;
-            if (n > 0)
-              x_offset += extra_repeat_overlap;
+            if (rtl)
+            {
+              x_offset -= width;
+              if (n > 0)
+                x_offset += extra_repeat_overlap;
+            }
             pos[k - 1].x_offset = x_offset;
             /* Append copy. */
             --j;
             info[j] = info[k - 1];
             pos[j] = pos[k - 1];
+
+            if (!rtl)
+            {
+              x_offset += width;
+              if (n > 0)
+                x_offset -= extra_repeat_overlap;
+            }
           }
         }
       }
@@ -625,6 +641,9 @@
       buffer->len = new_len;
     }
   }
+
+  if (!rtl)
+    buffer->reverse ();
 }
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh	2024-01-16 16:19:00.000000000 +0000
@@ -53,7 +53,7 @@
 };
 
 
-#line 54 "hb-ot-shaper-indic-machine.hh"
+#line 57 "hb-ot-shaper-indic-machine.hh"
 #define indic_syllable_machine_ex_A 9u
 #define indic_syllable_machine_ex_C 1u
 #define indic_syllable_machine_ex_CM 16u
@@ -76,7 +76,7 @@
 #define indic_syllable_machine_ex_ZWNJ 5u
 
 
-#line 75 "hb-ot-shaper-indic-machine.hh"
+#line 80 "hb-ot-shaper-indic-machine.hh"
 static const unsigned char _indic_syllable_machine_trans_keys[] = {
         8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
         8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
@@ -460,7 +460,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
 
-#line 453 "hb-ot-shaper-indic-machine.hh"
+#line 464 "hb-ot-shaper-indic-machine.hh"
         {
         cs = indic_syllable_machine_start;
         ts = 0;
@@ -476,7 +476,7 @@
 
   unsigned int syllable_serial = 1;
 
-#line 465 "hb-ot-shaper-indic-machine.hh"
+#line 480 "hb-ot-shaper-indic-machine.hh"
         {
         int _slen;
         int _trans;
@@ -490,7 +490,7 @@
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 477 "hb-ot-shaper-indic-machine.hh"
+#line 494 "hb-ot-shaper-indic-machine.hh"
         }
 
         _keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -593,7 +593,7 @@
 #line 114 "hb-ot-shaper-indic-machine.rl"
         {act = 6;}
         break;
-#line 559 "hb-ot-shaper-indic-machine.hh"
+#line 597 "hb-ot-shaper-indic-machine.hh"
         }
 
 _again:
@@ -602,7 +602,7 @@
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 566 "hb-ot-shaper-indic-machine.hh"
+#line 606 "hb-ot-shaper-indic-machine.hh"
         }
 
         if ( ++p != pe )
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc	2024-01-16 16:19:00.000000000 +0000
@@ -6,12 +6,12 @@
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # IndicPositionalCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
+ * # IndicSyllabicCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # IndicPositionalCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # Blocks-15.1.0.txt
+ * # Date: 2023-07-28, 15:47:20 GMT
  */
 
 #include "hb.hh"
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh	2024-01-16 16:19:00.000000000 +0000
@@ -48,7 +48,7 @@
 };
 
 
-#line 49 "hb-ot-shaper-khmer-machine.hh"
+#line 52 "hb-ot-shaper-khmer-machine.hh"
 #define khmer_syllable_machine_ex_C 1u
 #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u
 #define khmer_syllable_machine_ex_H 4u
@@ -66,7 +66,7 @@
 #define khmer_syllable_machine_ex_ZWNJ 5u
 
 
-#line 65 "hb-ot-shaper-khmer-machine.hh"
+#line 70 "hb-ot-shaper-khmer-machine.hh"
 static const unsigned char _khmer_syllable_machine_trans_keys[] = {
         5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u,
         5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u,
@@ -294,7 +294,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
 
-#line 287 "hb-ot-shaper-khmer-machine.hh"
+#line 298 "hb-ot-shaper-khmer-machine.hh"
         {
         cs = khmer_syllable_machine_start;
         ts = 0;
@@ -310,7 +310,7 @@
 
   unsigned int syllable_serial = 1;
 
-#line 299 "hb-ot-shaper-khmer-machine.hh"
+#line 314 "hb-ot-shaper-khmer-machine.hh"
         {
         int _slen;
         int _trans;
@@ -324,7 +324,7 @@
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 311 "hb-ot-shaper-khmer-machine.hh"
+#line 328 "hb-ot-shaper-khmer-machine.hh"
         }
 
         _keys = _khmer_syllable_machine_trans_keys + (cs<<1);
@@ -394,7 +394,7 @@
 #line 98 "hb-ot-shaper-khmer-machine.rl"
         {act = 3;}
         break;
-#line 368 "hb-ot-shaper-khmer-machine.hh"
+#line 398 "hb-ot-shaper-khmer-machine.hh"
         }
 
 _again:
@@ -403,7 +403,7 @@
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 375 "hb-ot-shaper-khmer-machine.hh"
+#line 407 "hb-ot-shaper-khmer-machine.hh"
         }
 
         if ( ++p != pe )
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh	2024-01-16 16:19:00.000000000 +0000
@@ -50,7 +50,7 @@
 };
 
 
-#line 51 "hb-ot-shaper-myanmar-machine.hh"
+#line 54 "hb-ot-shaper-myanmar-machine.hh"
 #define myanmar_syllable_machine_ex_A 9u
 #define myanmar_syllable_machine_ex_As 32u
 #define myanmar_syllable_machine_ex_C 1u
@@ -77,7 +77,7 @@
 #define myanmar_syllable_machine_ex_ZWNJ 5u
 
 
-#line 76 "hb-ot-shaper-myanmar-machine.hh"
+#line 81 "hb-ot-shaper-myanmar-machine.hh"
 static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
         1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u,
         5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u,
@@ -443,7 +443,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
 
-#line 436 "hb-ot-shaper-myanmar-machine.hh"
+#line 447 "hb-ot-shaper-myanmar-machine.hh"
         {
         cs = myanmar_syllable_machine_start;
         ts = 0;
@@ -459,7 +459,7 @@
 
   unsigned int syllable_serial = 1;
 
-#line 448 "hb-ot-shaper-myanmar-machine.hh"
+#line 463 "hb-ot-shaper-myanmar-machine.hh"
         {
         int _slen;
         int _trans;
@@ -473,7 +473,7 @@
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 460 "hb-ot-shaper-myanmar-machine.hh"
+#line 477 "hb-ot-shaper-myanmar-machine.hh"
         }
 
         _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -519,7 +519,7 @@
 #line 113 "hb-ot-shaper-myanmar-machine.rl"
         {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
         break;
-#line 498 "hb-ot-shaper-myanmar-machine.hh"
+#line 523 "hb-ot-shaper-myanmar-machine.hh"
         }
 
 _again:
@@ -528,7 +528,7 @@
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 505 "hb-ot-shaper-myanmar-machine.hh"
+#line 532 "hb-ot-shaper-myanmar-machine.hh"
         }
 
         if ( ++p != pe )
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc	2024-01-16 16:19:00.000000000 +0000
@@ -40,6 +40,14 @@
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return false;
   if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE)))
+  {
+    if (buffer->messaging ())
+      (void) buffer->message (font, "skipped inserting dotted-circles because there is no broken syllables");
+    return false;
+  }
+
+  if (buffer->messaging () &&
+      !buffer->message (font, "start inserting dotted-circles"))
     return false;
 
   hb_codepoint_t dottedcircle_glyph;
@@ -84,6 +92,10 @@
       (void) buffer->next_glyph ();
   }
   buffer->sync ();
+
+  if (buffer->messaging ())
+    (void) buffer->message (font, "end inserting dotted-circles");
+
   return true;
 }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh	2024-01-16 16:19:00.000000000 +0000
@@ -53,7 +53,7 @@
 };
 
 
-#line 54 "hb-ot-shaper-use-machine.hh"
+#line 57 "hb-ot-shaper-use-machine.hh"
 #define use_syllable_machine_ex_B 1u
 #define use_syllable_machine_ex_CGJ 6u
 #define use_syllable_machine_ex_CMAbv 31u
@@ -68,7 +68,9 @@
 #define use_syllable_machine_ex_G 49u
 #define use_syllable_machine_ex_GB 5u
 #define use_syllable_machine_ex_H 12u
+#define use_syllable_machine_ex_HM 54u
 #define use_syllable_machine_ex_HN 13u
+#define use_syllable_machine_ex_HR 55u
 #define use_syllable_machine_ex_HVM 53u
 #define use_syllable_machine_ex_IS 44u
 #define use_syllable_machine_ex_J 50u
@@ -97,673 +99,662 @@
 #define use_syllable_machine_ex_ZWNJ 14u
 
 
-#line 96 "hb-ot-shaper-use-machine.hh"
+#line 103 "hb-ot-shaper-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-        0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
-        14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
-        14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
-        12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 11u, 53u, 14u, 42u, 14u, 42u, 11u, 53u,
+        49u, 51u, 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u,
+        14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u,
+        14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u,
+        12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 53u,
+        1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u,
+        14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u,
+        14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u,
+        1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u,
+        14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u,
+        14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u,
+        14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u, 1u, 48u,
         11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u,
         14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u,
         14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u,
-        1u, 14u, 1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u,
-        14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u,
-        14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u,
-        12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u,
-        1u, 48u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
-        14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
-        14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
-        12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 11u, 53u,
-        14u, 42u, 14u, 42u, 1u, 5u, 14u, 52u, 14u, 52u, 14u, 51u, 0
+        1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 14u, 42u, 14u, 42u, 1u, 5u,
+        14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 53u, 0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-        54, 43, 43, 53, 35, 34, 34, 34,
-        33, 33, 1, 35, 35, 35, 14, 35,
-        40, 40, 40, 40, 42, 40, 42, 42,
-        42, 43, 14, 48, 43, 29, 29, 43,
+        3, 54, 43, 43, 53, 35, 34, 34,
+        34, 33, 33, 1, 35, 35, 35, 14,
+        35, 40, 40, 40, 40, 42, 40, 42,
+        42, 42, 43, 14, 48, 29, 29, 43,
+        53, 35, 34, 34, 34, 33, 33, 1,
+        35, 35, 35, 14, 35, 40, 40, 40,
+        40, 42, 40, 42, 42, 42, 43, 14,
+        14, 48, 2, 11, 43, 43, 53, 35,
+        34, 34, 34, 33, 33, 1, 35, 35,
+        35, 14, 35, 40, 40, 40, 40, 42,
+        40, 42, 42, 42, 43, 14, 14, 48,
         43, 53, 35, 34, 34, 34, 33, 33,
         1, 35, 35, 35, 14, 35, 40, 40,
         40, 40, 42, 40, 42, 42, 42, 43,
-        14, 14, 48, 2, 11, 43, 43, 53,
-        35, 34, 34, 34, 33, 33, 1, 35,
-        35, 35, 14, 35, 40, 40, 40, 40,
-        42, 40, 42, 42, 42, 43, 14, 14,
-        48, 43, 43, 53, 35, 34, 34, 34,
-        33, 33, 1, 35, 35, 35, 14, 35,
-        40, 40, 40, 40, 42, 40, 42, 42,
-        42, 43, 14, 48, 11, 2, 53, 43,
-        29, 29, 5, 39, 39, 38
+        14, 48, 11, 2, 53, 29, 29, 5,
+        42, 38, 39, 41, 43
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-        0, 55, 99, 143, 197, 233, 268, 303,
-        338, 372, 406, 408, 444, 480, 516, 531,
-        567, 608, 649, 690, 731, 774, 815, 858,
-        901, 944, 988, 1003, 1052, 1096, 1126, 1156,
-        1200, 1244, 1298, 1334, 1369, 1404, 1439, 1473,
-        1507, 1509, 1545, 1581, 1617, 1632, 1668, 1709,
-        1750, 1791, 1832, 1875, 1916, 1959, 2002, 2045,
-        2089, 2104, 2119, 2168, 2171, 2183, 2227, 2271,
-        2325, 2361, 2396, 2431, 2466, 2500, 2534, 2536,
-        2572, 2608, 2644, 2659, 2695, 2736, 2777, 2818,
-        2859, 2902, 2943, 2986, 3029, 3072, 3116, 3131,
-        3146, 3195, 3239, 3283, 3337, 3373, 3408, 3443,
-        3478, 3512, 3546, 3548, 3584, 3620, 3656, 3671,
-        3707, 3748, 3789, 3830, 3871, 3914, 3955, 3998,
-        4041, 4084, 4128, 4143, 4192, 4204, 4207, 4261,
-        4305, 4335, 4365, 4371, 4411, 4451
+        0, 4, 59, 103, 147, 201, 237, 272,
+        307, 342, 376, 410, 412, 448, 484, 520,
+        535, 571, 612, 653, 694, 735, 778, 819,
+        862, 905, 948, 992, 1007, 1056, 1086, 1116,
+        1160, 1214, 1250, 1285, 1320, 1355, 1389, 1423,
+        1425, 1461, 1497, 1533, 1548, 1584, 1625, 1666,
+        1707, 1748, 1791, 1832, 1875, 1918, 1961, 2005,
+        2020, 2035, 2084, 2087, 2099, 2143, 2187, 2241,
+        2277, 2312, 2347, 2382, 2416, 2450, 2452, 2488,
+        2524, 2560, 2575, 2611, 2652, 2693, 2734, 2775,
+        2818, 2859, 2902, 2945, 2988, 3032, 3047, 3062,
+        3111, 3155, 3209, 3245, 3280, 3315, 3350, 3384,
+        3418, 3420, 3456, 3492, 3528, 3543, 3579, 3620,
+        3661, 3702, 3743, 3786, 3827, 3870, 3913, 3956,
+        4000, 4015, 4064, 4076, 4079, 4133, 4163, 4193,
+        4199, 4242, 4281, 4321, 4363
 };
 
 static const unsigned char _use_syllable_machine_indicies[] = {
-        0, 1, 2, 2, 3, 4, 2, 2,
-        2, 2, 2, 5, 6, 7, 8, 2,
-        2, 2, 9, 2, 2, 2, 10, 11,
-        12, 13, 14, 15, 16, 17, 18, 19,
-        20, 21, 22, 23, 2, 24, 25, 26,
-        2, 27, 28, 29, 30, 31, 32, 33,
-        30, 34, 2, 35, 2, 36, 2, 38,
-        39, 37, 40, 37, 37, 37, 37, 37,
-        37, 37, 41, 42, 43, 44, 45, 46,
-        47, 48, 49, 50, 51, 52, 53, 54,
-        37, 55, 56, 57, 37, 58, 59, 37,
-        60, 61, 62, 63, 60, 37, 37, 37,
-        37, 64, 37, 38, 39, 37, 40, 37,
-        37, 37, 37, 37, 37, 37, 41, 42,
-        43, 44, 45, 46, 47, 48, 49, 51,
-        51, 52, 53, 54, 37, 55, 56, 57,
-        37, 37, 37, 37, 60, 61, 62, 63,
-        60, 37, 37, 37, 37, 64, 37, 38,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 42, 43, 44,
-        45, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 55, 56, 57, 37, 37,
-        37, 37, 37, 61, 62, 63, 65, 37,
-        37, 37, 37, 42, 37, 40, 37, 37,
-        37, 37, 37, 37, 37, 37, 42, 43,
-        44, 45, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 55, 56, 57, 37,
-        37, 37, 37, 37, 61, 62, 63, 65,
-        37, 40, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 43, 44, 45, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        61, 62, 63, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 44,
-        45, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 61, 62, 63, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 45, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 61, 62,
-        63, 37, 40, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 61, 62, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 62, 37, 40, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 55,
-        56, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 43, 44,
-        45, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 56, 57, 37, 37,
-        37, 37, 37, 61, 62, 63, 65, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 66, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 40, 37, 40, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 43, 44, 45,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 61, 62, 63, 65, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 41,
-        42, 43, 44, 45, 37, 37, 37, 37,
-        37, 37, 52, 53, 54, 37, 55, 56,
-        57, 37, 37, 37, 37, 37, 61, 62,
-        63, 65, 37, 37, 37, 37, 42, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 42, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 52, 53, 54, 37, 55,
-        56, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 37, 37, 37, 42,
-        37, 40, 37, 37, 37, 37, 37, 37,
-        37, 37, 42, 43, 44, 45, 37, 37,
-        37, 37, 37, 37, 37, 53, 54, 37,
-        55, 56, 57, 37, 37, 37, 37, 37,
-        61, 62, 63, 65, 37, 37, 37, 37,
-        42, 37, 40, 37, 37, 37, 37, 37,
-        37, 37, 37, 42, 43, 44, 45, 37,
-        37, 37, 37, 37, 37, 37, 37, 54,
-        37, 55, 56, 57, 37, 37, 37, 37,
-        37, 61, 62, 63, 65, 37, 37, 37,
-        37, 42, 37, 67, 37, 40, 37, 37,
-        37, 37, 37, 37, 37, 41, 42, 43,
-        44, 45, 37, 47, 48, 37, 37, 37,
-        52, 53, 54, 37, 55, 56, 57, 37,
-        37, 37, 37, 37, 61, 62, 63, 65,
-        37, 37, 37, 37, 42, 37, 40, 37,
-        37, 37, 37, 37, 37, 37, 37, 42,
-        43, 44, 45, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 55, 56, 57,
-        37, 37, 37, 37, 37, 61, 62, 63,
-        65, 37, 37, 37, 37, 42, 37, 67,
-        37, 40, 37, 37, 37, 37, 37, 37,
-        37, 41, 42, 43, 44, 45, 37, 37,
-        48, 37, 37, 37, 52, 53, 54, 37,
-        55, 56, 57, 37, 37, 37, 37, 37,
-        61, 62, 63, 65, 37, 37, 37, 37,
-        42, 37, 67, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 41, 42, 43, 44,
-        45, 37, 37, 37, 37, 37, 37, 52,
-        53, 54, 37, 55, 56, 57, 37, 37,
-        37, 37, 37, 61, 62, 63, 65, 37,
-        37, 37, 37, 42, 37, 67, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 41,
-        42, 43, 44, 45, 46, 47, 48, 37,
-        37, 37, 52, 53, 54, 37, 55, 56,
-        57, 37, 37, 37, 37, 37, 61, 62,
-        63, 65, 37, 37, 37, 37, 42, 37,
-        38, 39, 37, 40, 37, 37, 37, 37,
-        37, 37, 37, 41, 42, 43, 44, 45,
-        46, 47, 48, 49, 37, 51, 52, 53,
-        54, 37, 55, 56, 57, 37, 37, 37,
-        37, 60, 61, 62, 63, 60, 37, 37,
-        37, 37, 64, 37, 38, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 40, 37, 38, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 42, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 55,
-        56, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 38, 39, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 41,
-        42, 43, 44, 45, 46, 47, 48, 49,
-        50, 51, 52, 53, 54, 37, 55, 56,
-        57, 37, 37, 37, 37, 60, 61, 62,
-        63, 60, 37, 37, 37, 37, 64, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 58, 59, 37, 40, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 59, 37, 69, 70, 68, 71,
+        1, 0, 2, 0, 3, 4, 5, 5,
+        6, 7, 5, 5, 5, 5, 5, 8,
+        9, 10, 11, 5, 5, 5, 12, 5,
+        5, 5, 13, 14, 15, 16, 17, 18,
+        19, 20, 21, 8, 22, 23, 24, 25,
+        5, 26, 27, 28, 5, 29, 30, 31,
+        32, 33, 34, 35, 32, 1, 5, 36,
+        5, 37, 5, 39, 40, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 42, 43,
+        44, 45, 46, 47, 48, 49, 50, 39,
+        51, 52, 53, 54, 38, 55, 56, 57,
+        38, 58, 59, 38, 60, 61, 62, 63,
+        60, 38, 38, 38, 38, 64, 38, 39,
+        40, 38, 41, 38, 38, 38, 38, 38,
+        38, 38, 42, 43, 44, 45, 46, 47,
+        48, 49, 50, 39, 51, 52, 53, 54,
+        38, 55, 56, 57, 38, 38, 38, 38,
+        60, 61, 62, 63, 60, 38, 38, 38,
+        38, 64, 38, 39, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 43, 44, 45, 46, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 55,
+        56, 57, 38, 38, 38, 38, 38, 61,
+        62, 63, 65, 38, 38, 38, 38, 43,
+        38, 41, 38, 38, 38, 38, 38, 38,
+        38, 38, 43, 44, 45, 46, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        55, 56, 57, 38, 38, 38, 38, 38,
+        61, 62, 63, 65, 38, 41, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 44,
+        45, 46, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 61, 62, 63, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 45, 46, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 61,
+        62, 63, 38, 41, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 46,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 61, 62, 63, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 61, 62, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        62, 38, 41, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 55, 56, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 44, 45, 46, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        56, 57, 38, 38, 38, 38, 38, 61,
+        62, 63, 65, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        66, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 41, 38, 41,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 44, 45, 46, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 61, 62,
+        63, 65, 38, 41, 38, 38, 38, 38,
+        38, 38, 38, 42, 43, 44, 45, 46,
+        38, 38, 38, 38, 38, 38, 52, 53,
+        54, 38, 55, 56, 57, 38, 38, 38,
+        38, 38, 61, 62, 63, 65, 38, 38,
+        38, 38, 43, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 43, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 52,
+        53, 54, 38, 55, 56, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        38, 38, 38, 43, 38, 41, 38, 38,
+        38, 38, 38, 38, 38, 38, 43, 44,
+        45, 46, 38, 38, 38, 38, 38, 38,
+        38, 53, 54, 38, 55, 56, 57, 38,
+        38, 38, 38, 38, 61, 62, 63, 65,
+        38, 38, 38, 38, 43, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 38, 43,
+        44, 45, 46, 38, 38, 38, 38, 38,
+        38, 38, 38, 54, 38, 55, 56, 57,
+        38, 38, 38, 38, 38, 61, 62, 63,
+        65, 38, 38, 38, 38, 43, 38, 67,
+        38, 41, 38, 38, 38, 38, 38, 38,
+        38, 42, 43, 44, 45, 46, 38, 48,
+        49, 38, 38, 38, 52, 53, 54, 38,
+        55, 56, 57, 38, 38, 38, 38, 38,
+        61, 62, 63, 65, 38, 38, 38, 38,
+        43, 38, 41, 38, 38, 38, 38, 38,
+        38, 38, 38, 43, 44, 45, 46, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 55, 56, 57, 38, 38, 38, 38,
+        38, 61, 62, 63, 65, 38, 38, 38,
+        38, 43, 38, 67, 38, 41, 38, 38,
+        38, 38, 38, 38, 38, 42, 43, 44,
+        45, 46, 38, 38, 49, 38, 38, 38,
+        52, 53, 54, 38, 55, 56, 57, 38,
+        38, 38, 38, 38, 61, 62, 63, 65,
+        38, 38, 38, 38, 43, 38, 67, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        42, 43, 44, 45, 46, 38, 38, 38,
+        38, 38, 38, 52, 53, 54, 38, 55,
+        56, 57, 38, 38, 38, 38, 38, 61,
+        62, 63, 65, 38, 38, 38, 38, 43,
+        38, 67, 38, 41, 38, 38, 38, 38,
+        38, 38, 38, 42, 43, 44, 45, 46,
+        47, 48, 49, 38, 38, 38, 52, 53,
+        54, 38, 55, 56, 57, 38, 38, 38,
+        38, 38, 61, 62, 63, 65, 38, 38,
+        38, 38, 43, 38, 39, 40, 38, 41,
+        38, 38, 38, 38, 38, 38, 38, 42,
+        43, 44, 45, 46, 47, 48, 49, 50,
+        38, 51, 52, 53, 54, 38, 55, 56,
+        57, 38, 38, 38, 38, 60, 61, 62,
+        63, 60, 38, 38, 38, 38, 64, 38,
+        39, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 41, 38, 39,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 43, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 55, 56, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 58, 59, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 59, 38, 4, 69, 68, 70,
+        68, 68, 68, 68, 68, 68, 68, 71,
+        72, 73, 74, 75, 76, 77, 78, 79,
+        4, 80, 81, 82, 83, 68, 84, 85,
+        86, 68, 68, 68, 68, 87, 88, 89,
+        90, 91, 68, 68, 68, 68, 92, 68,
+        4, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 72, 73,
+        74, 75, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 84, 85, 86, 68,
+        68, 68, 68, 68, 88, 89, 90, 93,
+        68, 68, 68, 68, 72, 68, 70, 68,
         68, 68, 68, 68, 68, 68, 68, 72,
-        73, 74, 75, 76, 77, 78, 79, 80,
-        1, 81, 82, 83, 84, 68, 85, 86,
-        87, 68, 68, 68, 68, 88, 89, 90,
-        91, 92, 68, 68, 68, 68, 93, 68,
-        69, 70, 68, 71, 68, 68, 68, 68,
-        68, 68, 68, 72, 73, 74, 75, 76,
-        77, 78, 79, 80, 81, 81, 82, 83,
-        84, 68, 85, 86, 87, 68, 68, 68,
-        68, 88, 89, 90, 91, 92, 68, 68,
-        68, 68, 93, 68, 69, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 73, 74, 75, 76, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        85, 86, 87, 68, 68, 68, 68, 68,
-        89, 90, 91, 94, 68, 68, 68, 68,
-        73, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 68, 73, 74, 75, 76, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 85, 86, 87, 68, 68, 68, 68,
-        68, 89, 90, 91, 94, 68, 71, 68,
+        73, 74, 75, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 84, 85, 86,
+        68, 68, 68, 68, 68, 88, 89, 90,
+        93, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 73, 74, 75, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        74, 75, 76, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 89, 90, 91,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 75, 76, 68, 68,
+        68, 88, 89, 90, 68, 70, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
+        74, 75, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        89, 90, 91, 68, 71, 68, 68, 68,
+        68, 68, 68, 68, 88, 89, 90, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 75, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        76, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 88,
+        89, 90, 68, 70, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 89, 90, 91, 68, 71,
         68, 68, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 88, 89, 68, 70, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 89, 90,
-        68, 71, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 89, 68, 70,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 73, 74, 75, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 90, 68, 71, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 74,
-        75, 76, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 85, 86, 87, 68,
-        68, 68, 68, 68, 89, 90, 91, 94,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 74, 75, 76, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 86, 87, 68, 68, 68, 68, 68,
-        89, 90, 91, 94, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 74,
-        75, 76, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 87, 68,
-        68, 68, 68, 68, 89, 90, 91, 94,
-        68, 96, 95, 95, 95, 95, 95, 95,
-        95, 95, 95, 95, 95, 95, 97, 95,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 74, 75, 76, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 89,
-        90, 91, 94, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 72, 73, 74, 75,
-        76, 68, 68, 68, 68, 68, 68, 82,
-        83, 84, 68, 85, 86, 87, 68, 68,
-        68, 68, 68, 89, 90, 91, 94, 68,
-        68, 68, 68, 73, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 73, 74,
-        75, 76, 68, 68, 68, 68, 68, 68,
-        82, 83, 84, 68, 85, 86, 87, 68,
-        68, 68, 68, 68, 89, 90, 91, 94,
-        68, 68, 68, 68, 73, 68, 71, 68,
+        84, 85, 86, 68, 68, 68, 68, 68,
+        88, 89, 90, 93, 68, 70, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 73,
-        74, 75, 76, 68, 68, 68, 68, 68,
-        68, 68, 83, 84, 68, 85, 86, 87,
-        68, 68, 68, 68, 68, 89, 90, 91,
-        94, 68, 68, 68, 68, 73, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        73, 74, 75, 76, 68, 68, 68, 68,
-        68, 68, 68, 68, 84, 68, 85, 86,
-        87, 68, 68, 68, 68, 68, 89, 90,
-        91, 94, 68, 68, 68, 68, 73, 68,
-        98, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 72, 73, 74, 75, 76, 68,
-        78, 79, 68, 68, 68, 82, 83, 84,
-        68, 85, 86, 87, 68, 68, 68, 68,
-        68, 89, 90, 91, 94, 68, 68, 68,
-        68, 73, 68, 71, 68, 68, 68, 68,
-        68, 68, 68, 68, 73, 74, 75, 76,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 85, 86, 87, 68, 68, 68,
-        68, 68, 89, 90, 91, 94, 68, 68,
-        68, 68, 73, 68, 98, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 72, 73,
-        74, 75, 76, 68, 68, 79, 68, 68,
-        68, 82, 83, 84, 68, 85, 86, 87,
-        68, 68, 68, 68, 68, 89, 90, 91,
-        94, 68, 68, 68, 68, 73, 68, 98,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 72, 73, 74, 75, 76, 68, 68,
-        68, 68, 68, 68, 82, 83, 84, 68,
-        85, 86, 87, 68, 68, 68, 68, 68,
-        89, 90, 91, 94, 68, 68, 68, 68,
-        73, 68, 98, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 72, 73, 74, 75,
-        76, 77, 78, 79, 68, 68, 68, 82,
-        83, 84, 68, 85, 86, 87, 68, 68,
-        68, 68, 68, 89, 90, 91, 94, 68,
-        68, 68, 68, 73, 68, 69, 70, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        72, 73, 74, 75, 76, 77, 78, 79,
-        80, 68, 81, 82, 83, 84, 68, 85,
-        86, 87, 68, 68, 68, 68, 88, 89,
-        90, 91, 92, 68, 68, 68, 68, 93,
-        68, 69, 99, 99, 99, 99, 99, 99,
-        99, 99, 99, 99, 99, 99, 100, 99,
-        69, 95, 95, 95, 95, 95, 95, 95,
-        95, 95, 95, 95, 95, 97, 95, 69,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 73, 74, 75,
-        76, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 85, 86, 87, 68, 68,
-        68, 68, 68, 89, 90, 91, 94, 68,
-        102, 103, 101, 3, 104, 104, 104, 104,
-        104, 104, 104, 104, 104, 105, 104, 106,
-        107, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 108, 109, 110, 111, 112, 113,
-        114, 115, 116, 117, 118, 119, 120, 121,
-        68, 122, 123, 124, 68, 58, 59, 68,
-        125, 126, 127, 128, 129, 68, 68, 68,
-        68, 130, 68, 106, 107, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 108, 109,
-        110, 111, 112, 113, 114, 115, 116, 118,
-        118, 119, 120, 121, 68, 122, 123, 124,
-        68, 68, 68, 68, 125, 126, 127, 128,
-        129, 68, 68, 68, 68, 130, 68, 106,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 109, 110, 111,
-        112, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 122, 123, 124, 68, 68,
-        68, 68, 68, 126, 127, 128, 131, 68,
-        68, 68, 68, 109, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 109, 110,
-        111, 112, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 122, 123, 124, 68,
-        68, 68, 68, 68, 126, 127, 128, 131,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 110, 111, 112, 68, 68,
+        74, 75, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 85, 86, 68,
+        68, 68, 68, 68, 88, 89, 90, 93,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 73, 74, 75, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 86, 68, 68, 68, 68, 68,
+        88, 89, 90, 93, 68, 95, 94, 94,
+        94, 94, 94, 94, 94, 94, 94, 94,
+        94, 94, 96, 94, 70, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 73, 74,
+        75, 68, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 88, 89, 90, 93, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        71, 72, 73, 74, 75, 68, 68, 68,
+        68, 68, 68, 81, 82, 83, 68, 84,
+        85, 86, 68, 68, 68, 68, 68, 88,
+        89, 90, 93, 68, 68, 68, 68, 72,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 72, 73, 74, 75, 68, 68,
+        68, 68, 68, 68, 81, 82, 83, 68,
+        84, 85, 86, 68, 68, 68, 68, 68,
+        88, 89, 90, 93, 68, 68, 68, 68,
+        72, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 68, 72, 73, 74, 75, 68,
+        68, 68, 68, 68, 68, 68, 82, 83,
+        68, 84, 85, 86, 68, 68, 68, 68,
+        68, 88, 89, 90, 93, 68, 68, 68,
+        68, 72, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 68, 72, 73, 74, 75,
         68, 68, 68, 68, 68, 68, 68, 68,
-        126, 127, 128, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 111,
-        112, 68, 68, 68, 68, 68, 68, 68,
+        83, 68, 84, 85, 86, 68, 68, 68,
+        68, 68, 88, 89, 90, 93, 68, 68,
+        68, 68, 72, 68, 97, 68, 70, 68,
+        68, 68, 68, 68, 68, 68, 71, 72,
+        73, 74, 75, 68, 77, 78, 68, 68,
+        68, 81, 82, 83, 68, 84, 85, 86,
+        68, 68, 68, 68, 68, 88, 89, 90,
+        93, 68, 68, 68, 68, 72, 68, 70,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        72, 73, 74, 75, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 84, 85,
+        86, 68, 68, 68, 68, 68, 88, 89,
+        90, 93, 68, 68, 68, 68, 72, 68,
+        97, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 71, 72, 73, 74, 75, 68,
+        68, 78, 68, 68, 68, 81, 82, 83,
+        68, 84, 85, 86, 68, 68, 68, 68,
+        68, 88, 89, 90, 93, 68, 68, 68,
+        68, 72, 68, 97, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 71, 72, 73,
+        74, 75, 68, 68, 68, 68, 68, 68,
+        81, 82, 83, 68, 84, 85, 86, 68,
+        68, 68, 68, 68, 88, 89, 90, 93,
+        68, 68, 68, 68, 72, 68, 97, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        71, 72, 73, 74, 75, 76, 77, 78,
+        68, 68, 68, 81, 82, 83, 68, 84,
+        85, 86, 68, 68, 68, 68, 68, 88,
+        89, 90, 93, 68, 68, 68, 68, 72,
+        68, 4, 69, 68, 70, 68, 68, 68,
+        68, 68, 68, 68, 71, 72, 73, 74,
+        75, 76, 77, 78, 79, 68, 80, 81,
+        82, 83, 68, 84, 85, 86, 68, 68,
+        68, 68, 87, 88, 89, 90, 91, 68,
+        68, 68, 68, 92, 68, 4, 98, 98,
+        98, 98, 98, 98, 98, 98, 98, 98,
+        98, 98, 99, 98, 4, 94, 94, 94,
+        94, 94, 94, 94, 94, 94, 94, 94,
+        94, 96, 94, 4, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 72, 73, 74, 75, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 84,
+        85, 86, 68, 68, 68, 68, 68, 88,
+        89, 90, 93, 68, 101, 102, 100, 6,
+        103, 103, 103, 103, 103, 103, 103, 103,
+        103, 104, 103, 105, 106, 68, 70, 68,
+        68, 68, 68, 68, 68, 68, 107, 108,
+        109, 110, 111, 112, 113, 114, 115, 105,
+        116, 117, 118, 119, 68, 120, 121, 122,
+        68, 58, 59, 68, 123, 124, 125, 126,
+        127, 68, 68, 68, 68, 128, 68, 105,
+        106, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 107, 108, 109, 110, 111, 112,
+        113, 114, 115, 105, 116, 117, 118, 119,
+        68, 120, 121, 122, 68, 68, 68, 68,
+        123, 124, 125, 126, 127, 68, 68, 68,
+        68, 128, 68, 105, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 108, 109, 110, 111, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 120,
+        121, 122, 68, 68, 68, 68, 68, 124,
+        125, 126, 129, 68, 68, 68, 68, 108,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 108, 109, 110, 111, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 126, 127, 128, 68, 71,
+        120, 121, 122, 68, 68, 68, 68, 68,
+        124, 125, 126, 129, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 109,
+        110, 111, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 112, 68, 68, 68, 68,
+        68, 68, 68, 68, 124, 125, 126, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 110, 111, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 126, 127,
-        128, 68, 71, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 124,
+        125, 126, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 111,
         68, 68, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 124, 125, 126, 68, 70, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 126, 127, 68, 71, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 124, 125, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 127, 68, 71, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 110, 111, 112, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 122,
-        123, 124, 68, 68, 68, 68, 68, 126,
-        127, 128, 131, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 110, 111,
-        112, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 123, 124, 68, 68,
-        68, 68, 68, 126, 127, 128, 131, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 110, 111, 112, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 124, 68, 68, 68, 68, 68, 126,
-        127, 128, 131, 68, 132, 95, 95, 95,
-        95, 95, 95, 95, 95, 95, 95, 95,
-        95, 97, 95, 71, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 110, 111, 112,
         68, 68, 68, 68, 68, 68, 68, 68,
+        125, 68, 70, 68, 70, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 109, 110,
+        111, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 120, 121, 122, 68, 68,
+        68, 68, 68, 124, 125, 126, 129, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 109, 110, 111, 68, 68, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 126, 127, 128, 131, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 108,
-        109, 110, 111, 112, 68, 68, 68, 68,
-        68, 68, 119, 120, 121, 68, 122, 123,
-        124, 68, 68, 68, 68, 68, 126, 127,
-        128, 131, 68, 68, 68, 68, 109, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 109, 110, 111, 112, 68, 68, 68,
-        68, 68, 68, 119, 120, 121, 68, 122,
-        123, 124, 68, 68, 68, 68, 68, 126,
-        127, 128, 131, 68, 68, 68, 68, 109,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 109, 110, 111, 112, 68, 68,
-        68, 68, 68, 68, 68, 120, 121, 68,
-        122, 123, 124, 68, 68, 68, 68, 68,
-        126, 127, 128, 131, 68, 68, 68, 68,
-        109, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 68, 109, 110, 111, 112, 68,
-        68, 68, 68, 68, 68, 68, 68, 121,
-        68, 122, 123, 124, 68, 68, 68, 68,
-        68, 126, 127, 128, 131, 68, 68, 68,
-        68, 109, 68, 133, 68, 71, 68, 68,
+        121, 122, 68, 68, 68, 68, 68, 124,
+        125, 126, 129, 68, 70, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 109, 110,
+        111, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 122, 68, 68,
+        68, 68, 68, 124, 125, 126, 129, 68,
+        130, 94, 94, 94, 94, 94, 94, 94,
+        94, 94, 94, 94, 94, 96, 94, 70,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 109, 110, 111, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 124, 125,
+        126, 129, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 107, 108, 109, 110, 111,
+        68, 68, 68, 68, 68, 68, 117, 118,
+        119, 68, 120, 121, 122, 68, 68, 68,
+        68, 68, 124, 125, 126, 129, 68, 68,
+        68, 68, 108, 68, 70, 68, 68, 68,
         68, 68, 68, 68, 68, 108, 109, 110,
-        111, 112, 68, 114, 115, 68, 68, 68,
-        119, 120, 121, 68, 122, 123, 124, 68,
-        68, 68, 68, 68, 126, 127, 128, 131,
-        68, 68, 68, 68, 109, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 68, 109,
-        110, 111, 112, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 122, 123, 124,
-        68, 68, 68, 68, 68, 126, 127, 128,
-        131, 68, 68, 68, 68, 109, 68, 133,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 108, 109, 110, 111, 112, 68, 68,
-        115, 68, 68, 68, 119, 120, 121, 68,
-        122, 123, 124, 68, 68, 68, 68, 68,
-        126, 127, 128, 131, 68, 68, 68, 68,
-        109, 68, 133, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 108, 109, 110, 111,
-        112, 68, 68, 68, 68, 68, 68, 119,
-        120, 121, 68, 122, 123, 124, 68, 68,
-        68, 68, 68, 126, 127, 128, 131, 68,
-        68, 68, 68, 109, 68, 133, 68, 71,
+        111, 68, 68, 68, 68, 68, 68, 117,
+        118, 119, 68, 120, 121, 122, 68, 68,
+        68, 68, 68, 124, 125, 126, 129, 68,
+        68, 68, 68, 108, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 108, 109,
+        110, 111, 68, 68, 68, 68, 68, 68,
+        68, 118, 119, 68, 120, 121, 122, 68,
+        68, 68, 68, 68, 124, 125, 126, 129,
+        68, 68, 68, 68, 108, 68, 70, 68,
         68, 68, 68, 68, 68, 68, 68, 108,
-        109, 110, 111, 112, 113, 114, 115, 68,
-        68, 68, 119, 120, 121, 68, 122, 123,
-        124, 68, 68, 68, 68, 68, 126, 127,
-        128, 131, 68, 68, 68, 68, 109, 68,
-        106, 107, 68, 71, 68, 68, 68, 68,
-        68, 68, 68, 108, 109, 110, 111, 112,
-        113, 114, 115, 116, 68, 118, 119, 120,
-        121, 68, 122, 123, 124, 68, 68, 68,
-        68, 125, 126, 127, 128, 129, 68, 68,
-        68, 68, 130, 68, 106, 99, 99, 99,
-        99, 99, 99, 99, 99, 99, 99, 99,
-        99, 100, 99, 106, 95, 95, 95, 95,
-        95, 95, 95, 95, 95, 95, 95, 95,
-        97, 95, 106, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 71,
+        109, 110, 111, 68, 68, 68, 68, 68,
+        68, 68, 68, 119, 68, 120, 121, 122,
+        68, 68, 68, 68, 68, 124, 125, 126,
+        129, 68, 68, 68, 68, 108, 68, 131,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 107, 108, 109, 110, 111, 68, 113,
+        114, 68, 68, 68, 117, 118, 119, 68,
+        120, 121, 122, 68, 68, 68, 68, 68,
+        124, 125, 126, 129, 68, 68, 68, 68,
+        108, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 68, 108, 109, 110, 111, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 120, 121, 122, 68, 68, 68, 68,
+        68, 124, 125, 126, 129, 68, 68, 68,
+        68, 108, 68, 131, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 107, 108, 109,
+        110, 111, 68, 68, 114, 68, 68, 68,
+        117, 118, 119, 68, 120, 121, 122, 68,
+        68, 68, 68, 68, 124, 125, 126, 129,
+        68, 68, 68, 68, 108, 68, 131, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        107, 108, 109, 110, 111, 68, 68, 68,
+        68, 68, 68, 117, 118, 119, 68, 120,
+        121, 122, 68, 68, 68, 68, 68, 124,
+        125, 126, 129, 68, 68, 68, 68, 108,
+        68, 131, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 107, 108, 109, 110, 111,
+        112, 113, 114, 68, 68, 68, 117, 118,
+        119, 68, 120, 121, 122, 68, 68, 68,
+        68, 68, 124, 125, 126, 129, 68, 68,
+        68, 68, 108, 68, 105, 106, 68, 70,
+        68, 68, 68, 68, 68, 68, 68, 107,
+        108, 109, 110, 111, 112, 113, 114, 115,
+        68, 116, 117, 118, 119, 68, 120, 121,
+        122, 68, 68, 68, 68, 123, 124, 125,
+        126, 127, 68, 68, 68, 68, 128, 68,
+        105, 98, 98, 98, 98, 98, 98, 98,
+        98, 98, 98, 98, 98, 99, 98, 105,
+        94, 94, 94, 94, 94, 94, 94, 94,
+        94, 94, 94, 94, 96, 94, 105, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        109, 110, 111, 112, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 122, 123,
-        124, 68, 68, 68, 68, 68, 126, 127,
-        128, 131, 68, 106, 107, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 108, 109,
-        110, 111, 112, 113, 114, 115, 116, 117,
-        118, 119, 120, 121, 68, 122, 123, 124,
-        68, 68, 68, 68, 125, 126, 127, 128,
-        129, 68, 68, 68, 68, 130, 68, 5,
-        6, 134, 8, 134, 134, 134, 134, 134,
-        134, 134, 10, 11, 12, 13, 14, 15,
-        16, 17, 18, 20, 20, 21, 22, 23,
-        134, 24, 25, 26, 134, 134, 134, 134,
-        30, 31, 32, 33, 30, 134, 134, 134,
-        134, 36, 134, 5, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 11, 12, 13, 14, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 24,
-        25, 26, 134, 134, 134, 134, 134, 31,
-        32, 33, 135, 134, 134, 134, 134, 11,
-        134, 8, 134, 134, 134, 134, 134, 134,
-        134, 134, 11, 12, 13, 14, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        24, 25, 26, 134, 134, 134, 134, 134,
-        31, 32, 33, 135, 134, 8, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 12,
-        13, 14, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 31, 32, 33, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 13, 14, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 31,
-        32, 33, 134, 8, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 14,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 31, 32, 33, 134, 8, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 31, 32, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        32, 134, 8, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 24, 25, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 12, 13, 14, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        25, 26, 134, 134, 134, 134, 134, 31,
-        32, 33, 135, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        136, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 8, 134, 8,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 12, 13, 14, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 31, 32,
-        33, 135, 134, 8, 134, 134, 134, 134,
-        134, 134, 134, 10, 11, 12, 13, 14,
-        134, 134, 134, 134, 134, 134, 21, 22,
-        23, 134, 24, 25, 26, 134, 134, 134,
-        134, 134, 31, 32, 33, 135, 134, 134,
-        134, 134, 11, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 11, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 21,
-        22, 23, 134, 24, 25, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        134, 134, 134, 11, 134, 8, 134, 134,
-        134, 134, 134, 134, 134, 134, 11, 12,
-        13, 14, 134, 134, 134, 134, 134, 134,
-        134, 22, 23, 134, 24, 25, 26, 134,
-        134, 134, 134, 134, 31, 32, 33, 135,
-        134, 134, 134, 134, 11, 134, 8, 134,
-        134, 134, 134, 134, 134, 134, 134, 11,
-        12, 13, 14, 134, 134, 134, 134, 134,
-        134, 134, 134, 23, 134, 24, 25, 26,
-        134, 134, 134, 134, 134, 31, 32, 33,
-        135, 134, 134, 134, 134, 11, 134, 137,
-        134, 8, 134, 134, 134, 134, 134, 134,
-        134, 10, 11, 12, 13, 14, 134, 16,
-        17, 134, 134, 134, 21, 22, 23, 134,
-        24, 25, 26, 134, 134, 134, 134, 134,
-        31, 32, 33, 135, 134, 134, 134, 134,
-        11, 134, 8, 134, 134, 134, 134, 134,
-        134, 134, 134, 11, 12, 13, 14, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 24, 25, 26, 134, 134, 134, 134,
-        134, 31, 32, 33, 135, 134, 134, 134,
-        134, 11, 134, 137, 134, 8, 134, 134,
-        134, 134, 134, 134, 134, 10, 11, 12,
-        13, 14, 134, 134, 17, 134, 134, 134,
-        21, 22, 23, 134, 24, 25, 26, 134,
-        134, 134, 134, 134, 31, 32, 33, 135,
-        134, 134, 134, 134, 11, 134, 137, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        10, 11, 12, 13, 14, 134, 134, 134,
-        134, 134, 134, 21, 22, 23, 134, 24,
-        25, 26, 134, 134, 134, 134, 134, 31,
-        32, 33, 135, 134, 134, 134, 134, 11,
-        134, 137, 134, 8, 134, 134, 134, 134,
-        134, 134, 134, 10, 11, 12, 13, 14,
-        15, 16, 17, 134, 134, 134, 21, 22,
-        23, 134, 24, 25, 26, 134, 134, 134,
-        134, 134, 31, 32, 33, 135, 134, 134,
-        134, 134, 11, 134, 5, 6, 134, 8,
-        134, 134, 134, 134, 134, 134, 134, 10,
-        11, 12, 13, 14, 15, 16, 17, 18,
-        134, 20, 21, 22, 23, 134, 24, 25,
-        26, 134, 134, 134, 134, 30, 31, 32,
-        33, 30, 134, 134, 134, 134, 36, 134,
-        5, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 8, 134, 5,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 11, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 24, 25, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        138, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 8, 134, 7, 8, 134, 1,
-        134, 134, 134, 1, 134, 134, 134, 134,
-        134, 5, 6, 7, 8, 134, 134, 134,
-        134, 134, 134, 134, 10, 11, 12, 13,
+        68, 68, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 68, 108, 109, 110, 111,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 120, 121, 122, 68, 68, 68,
+        68, 68, 124, 125, 126, 129, 68, 8,
+        9, 132, 11, 132, 132, 132, 132, 132,
+        132, 132, 13, 14, 15, 16, 17, 18,
+        19, 20, 21, 8, 22, 23, 24, 25,
+        132, 26, 27, 28, 132, 132, 132, 132,
+        32, 33, 34, 35, 32, 132, 132, 132,
+        132, 37, 132, 8, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 14, 15, 16, 17, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 26,
+        27, 28, 132, 132, 132, 132, 132, 33,
+        34, 35, 133, 132, 132, 132, 132, 14,
+        132, 11, 132, 132, 132, 132, 132, 132,
+        132, 132, 14, 15, 16, 17, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        26, 27, 28, 132, 132, 132, 132, 132,
+        33, 34, 35, 133, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 15,
+        16, 17, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 33, 34, 35, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 16, 17, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 33,
+        34, 35, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 17,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 33, 34, 35, 132, 11, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 33, 34, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        34, 132, 11, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 26, 27, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 15, 16, 17, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        27, 28, 132, 132, 132, 132, 132, 33,
+        34, 35, 133, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        134, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 11, 132, 11,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 15, 16, 17, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 33, 34,
+        35, 133, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 13, 14, 15, 16, 17,
+        132, 132, 132, 132, 132, 132, 23, 24,
+        25, 132, 26, 27, 28, 132, 132, 132,
+        132, 132, 33, 34, 35, 133, 132, 132,
+        132, 132, 14, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 14, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 23,
+        24, 25, 132, 26, 27, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        132, 132, 132, 14, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 132, 14, 15,
+        16, 17, 132, 132, 132, 132, 132, 132,
+        132, 24, 25, 132, 26, 27, 28, 132,
+        132, 132, 132, 132, 33, 34, 35, 133,
+        132, 132, 132, 132, 14, 132, 11, 132,
+        132, 132, 132, 132, 132, 132, 132, 14,
+        15, 16, 17, 132, 132, 132, 132, 132,
+        132, 132, 132, 25, 132, 26, 27, 28,
+        132, 132, 132, 132, 132, 33, 34, 35,
+        133, 132, 132, 132, 132, 14, 132, 135,
+        132, 11, 132, 132, 132, 132, 132, 132,
+        132, 13, 14, 15, 16, 17, 132, 19,
+        20, 132, 132, 132, 23, 24, 25, 132,
+        26, 27, 28, 132, 132, 132, 132, 132,
+        33, 34, 35, 133, 132, 132, 132, 132,
+        14, 132, 11, 132, 132, 132, 132, 132,
+        132, 132, 132, 14, 15, 16, 17, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 26, 27, 28, 132, 132, 132, 132,
+        132, 33, 34, 35, 133, 132, 132, 132,
+        132, 14, 132, 135, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 13, 14, 15,
+        16, 17, 132, 132, 20, 132, 132, 132,
+        23, 24, 25, 132, 26, 27, 28, 132,
+        132, 132, 132, 132, 33, 34, 35, 133,
+        132, 132, 132, 132, 14, 132, 135, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        13, 14, 15, 16, 17, 132, 132, 132,
+        132, 132, 132, 23, 24, 25, 132, 26,
+        27, 28, 132, 132, 132, 132, 132, 33,
+        34, 35, 133, 132, 132, 132, 132, 14,
+        132, 135, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 13, 14, 15, 16, 17,
+        18, 19, 20, 132, 132, 132, 23, 24,
+        25, 132, 26, 27, 28, 132, 132, 132,
+        132, 132, 33, 34, 35, 133, 132, 132,
+        132, 132, 14, 132, 8, 9, 132, 11,
+        132, 132, 132, 132, 132, 132, 132, 13,
         14, 15, 16, 17, 18, 19, 20, 21,
-        22, 23, 134, 24, 25, 26, 134, 27,
-        28, 134, 30, 31, 32, 33, 30, 134,
-        134, 134, 134, 36, 134, 5, 6, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        10, 11, 12, 13, 14, 15, 16, 17,
-        18, 19, 20, 21, 22, 23, 134, 24,
-        25, 26, 134, 134, 134, 134, 30, 31,
-        32, 33, 30, 134, 134, 134, 134, 36,
-        134, 8, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 27, 28, 134, 8,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 28, 134, 1, 139, 139,
-        139, 1, 139, 141, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 142,
-        140, 34, 140, 141, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 34, 142,
-        140, 142, 140, 141, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 34, 140,
-        35, 140, 0
+        132, 22, 23, 24, 25, 132, 26, 27,
+        28, 132, 132, 132, 132, 32, 33, 34,
+        35, 32, 132, 132, 132, 132, 37, 132,
+        8, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 11, 132, 8,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 14, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 26, 27, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        136, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 11, 132, 10, 11, 132, 4,
+        132, 132, 132, 4, 132, 132, 132, 132,
+        132, 8, 9, 10, 11, 132, 132, 132,
+        132, 132, 132, 132, 13, 14, 15, 16,
+        17, 18, 19, 20, 21, 8, 22, 23,
+        24, 25, 132, 26, 27, 28, 132, 29,
+        30, 132, 32, 33, 34, 35, 32, 132,
+        132, 132, 132, 37, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        29, 30, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 30,
+        132, 4, 137, 137, 137, 4, 137, 139,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 140, 138, 141, 138, 141,
+        142, 138, 139, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 1, 140, 140,
+        138, 139, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 140, 138, 141,
+        138, 139, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 140, 138, 141,
+        138, 141, 138, 39, 40, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 42, 43,
+        44, 45, 46, 47, 48, 49, 50, 39,
+        51, 52, 53, 54, 38, 55, 56, 57,
+        38, 58, 59, 38, 60, 61, 62, 63,
+        60, 1, 38, 2, 38, 64, 38, 0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-        1, 31, 0, 59, 61, 90, 91, 116,
-        0, 118, 104, 92, 93, 94, 95, 108,
-        110, 111, 112, 119, 113, 105, 106, 107,
-        99, 100, 101, 120, 121, 122, 114, 96,
-        97, 98, 123, 125, 115, 0, 2, 3,
-        0, 16, 4, 5, 6, 7, 20, 22,
-        23, 24, 28, 25, 17, 18, 19, 11,
-        12, 13, 29, 30, 26, 8, 9, 10,
-        27, 14, 15, 21, 0, 32, 33, 0,
-        46, 34, 35, 36, 37, 50, 52, 53,
-        54, 55, 47, 48, 49, 41, 42, 43,
-        56, 38, 39, 40, 57, 58, 44, 0,
-        45, 0, 51, 0, 0, 0, 60, 0,
-        0, 0, 62, 63, 76, 64, 65, 66,
-        67, 80, 82, 83, 84, 89, 85, 77,
-        78, 79, 71, 72, 73, 86, 68, 69,
-        70, 87, 88, 74, 75, 81, 0, 102,
-        103, 109, 117, 0, 0, 0, 124
+        1, 120, 0, 2, 31, 1, 58, 60,
+        88, 89, 114, 1, 116, 102, 90, 91,
+        92, 93, 106, 108, 109, 110, 111, 103,
+        104, 105, 97, 98, 99, 117, 118, 119,
+        112, 94, 95, 96, 124, 113, 1, 3,
+        4, 1, 17, 5, 6, 7, 8, 21,
+        23, 24, 25, 26, 18, 19, 20, 12,
+        13, 14, 29, 30, 27, 9, 10, 11,
+        28, 15, 16, 22, 1, 32, 1, 45,
+        33, 34, 35, 36, 49, 51, 52, 53,
+        54, 46, 47, 48, 40, 41, 42, 55,
+        37, 38, 39, 56, 57, 43, 1, 44,
+        1, 50, 1, 1, 1, 59, 1, 1,
+        1, 61, 62, 75, 63, 64, 65, 66,
+        79, 81, 82, 83, 84, 76, 77, 78,
+        70, 71, 72, 85, 67, 68, 69, 86,
+        87, 73, 74, 80, 1, 100, 101, 107,
+        115, 1, 1, 1, 121, 122, 123
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
-        0, 0, 3, 0, 0, 0, 0, 0,
-        4, 0, 0, 0, 0, 0, 0, 0,
+        1, 0, 0, 0, 0, 4, 0, 0,
+        0, 0, 0, 5, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 5, 0, 0,
-        6, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 6, 0, 7, 0,
+        0, 8, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 7, 0, 0, 8,
+        0, 0, 0, 0, 9, 0, 10, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 9,
-        0, 10, 0, 11, 12, 13, 0, 14,
-        15, 16, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 11, 0,
+        12, 0, 13, 14, 15, 0, 16, 17,
+        18, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 17, 0,
-        0, 0, 0, 18, 19, 20, 0
+        0, 0, 0, 0, 19, 0, 0, 0,
+        0, 20, 21, 22, 0, 0, 0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
-        1, 0, 0, 0, 0, 0, 0, 0,
+        0, 2, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
@@ -778,11 +769,11 @@
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0
+        0, 0, 0, 0, 0
 };
 
 static const char _use_syllable_machine_from_state_actions[] = {
-        2, 0, 0, 0, 0, 0, 0, 0,
+        0, 3, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
@@ -797,40 +788,40 @@
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0
+        0, 0, 0, 0, 0
 };
 
 static const short _use_syllable_machine_eof_trans[] = {
-        0, 38, 38, 38, 38, 38, 38, 38,
-        38, 38, 38, 38, 38, 38, 38, 38,
-        38, 38, 38, 38, 38, 38, 38, 38,
-        38, 38, 38, 38, 38, 38, 38, 69,
+        1, 0, 39, 39, 39, 39, 39, 39,
+        39, 39, 39, 39, 39, 39, 39, 39,
+        39, 39, 39, 39, 39, 39, 39, 39,
+        39, 39, 39, 39, 39, 39, 39, 69,
         69, 69, 69, 69, 69, 69, 69, 69,
-        69, 69, 69, 69, 96, 69, 69, 69,
+        69, 69, 69, 95, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 69, 69, 99,
+        95, 69, 101, 104, 69, 69, 69, 69,
         69, 69, 69, 69, 69, 69, 69, 69,
-        100, 96, 69, 102, 105, 69, 69, 69,
-        69, 69, 69, 69, 69, 69, 69, 69,
-        69, 69, 96, 69, 69, 69, 69, 69,
-        69, 69, 69, 69, 69, 69, 100, 96,
-        69, 69, 135, 135, 135, 135, 135, 135,
-        135, 135, 135, 135, 135, 135, 135, 135,
-        135, 135, 135, 135, 135, 135, 135, 135,
-        135, 135, 135, 135, 135, 135, 135, 135,
-        135, 135, 140, 141, 141, 141
+        69, 95, 69, 69, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 99, 95, 69,
+        133, 133, 133, 133, 133, 133, 133, 133,
+        133, 133, 133, 133, 133, 133, 133, 133,
+        133, 133, 133, 133, 133, 133, 133, 133,
+        133, 133, 133, 133, 133, 133, 133, 138,
+        139, 139, 139, 139, 39
 };
 
-static const int use_syllable_machine_start = 0;
-static const int use_syllable_machine_first_final = 0;
+static const int use_syllable_machine_start = 1;
+static const int use_syllable_machine_first_final = 1;
 static const int use_syllable_machine_error = -1;
 
-static const int use_syllable_machine_en_main = 0;
+static const int use_syllable_machine_en_main = 1;
 
 
 #line 58 "hb-ot-shaper-use-machine.rl"
 
 
 
-#line 182 "hb-ot-shaper-use-machine.rl"
+#line 184 "hb-ot-shaper-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -929,7 +920,7 @@
   unsigned int act HB_UNUSED;
   int cs;
 
-#line 922 "hb-ot-shaper-use-machine.hh"
+#line 924 "hb-ot-shaper-use-machine.hh"
         {
         cs = use_syllable_machine_start;
         ts = 0;
@@ -937,12 +928,12 @@
         act = 0;
         }
 
-#line 282 "hb-ot-shaper-use-machine.rl"
+#line 284 "hb-ot-shaper-use-machine.rl"
 
 
   unsigned int syllable_serial = 1;
 
-#line 931 "hb-ot-shaper-use-machine.hh"
+#line 937 "hb-ot-shaper-use-machine.hh"
         {
         int _slen;
         int _trans;
@@ -952,11 +943,11 @@
                 goto _test_eof;
 _resume:
         switch ( _use_syllable_machine_from_state_actions[cs] ) {
-        case 2:
+        case 3:
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 943 "hb-ot-shaper-use-machine.hh"
+#line 951 "hb-ot-shaper-use-machine.hh"
         }
 
         _keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -974,88 +965,96 @@
                 goto _again;
 
         switch ( _use_syllable_machine_trans_actions[_trans] ) {
-        case 12:
-#line 170 "hb-ot-shaper-use-machine.rl"
+        case 6:
+#line 1 "NONE"
+        {te = p+1;}
+        break;
+        case 14:
+#line 172 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_virama_terminated_cluster); }}
         break;
-        case 10:
-#line 171 "hb-ot-shaper-use-machine.rl"
+        case 12:
+#line 173 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }}
         break;
-        case 8:
-#line 172 "hb-ot-shaper-use-machine.rl"
+        case 10:
+#line 174 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_standard_cluster); }}
         break;
-        case 16:
-#line 173 "hb-ot-shaper-use-machine.rl"
+        case 18:
+#line 175 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }}
         break;
-        case 14:
-#line 174 "hb-ot-shaper-use-machine.rl"
+        case 16:
+#line 176 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_numeral_cluster); }}
         break;
-        case 6:
-#line 175 "hb-ot-shaper-use-machine.rl"
+        case 8:
+#line 177 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_symbol_cluster); }}
         break;
-        case 20:
-#line 176 "hb-ot-shaper-use-machine.rl"
+        case 22:
+#line 178 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_hieroglyph_cluster); }}
         break;
-        case 4:
-#line 177 "hb-ot-shaper-use-machine.rl"
+        case 5:
+#line 179 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
         break;
-        case 3:
-#line 178 "hb-ot-shaper-use-machine.rl"
+        case 4:
+#line 180 "hb-ot-shaper-use-machine.rl"
         {te = p+1;{ found_syllable (use_non_cluster); }}
         break;
-        case 11:
-#line 170 "hb-ot-shaper-use-machine.rl"
+        case 13:
+#line 172 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
         break;
-        case 9:
-#line 171 "hb-ot-shaper-use-machine.rl"
+        case 11:
+#line 173 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
         break;
-        case 7:
-#line 172 "hb-ot-shaper-use-machine.rl"
+        case 9:
+#line 174 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_standard_cluster); }}
         break;
-        case 15:
-#line 173 "hb-ot-shaper-use-machine.rl"
+        case 17:
+#line 175 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
         break;
-        case 13:
-#line 174 "hb-ot-shaper-use-machine.rl"
+        case 15:
+#line 176 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_numeral_cluster); }}
         break;
-        case 5:
-#line 175 "hb-ot-shaper-use-machine.rl"
+        case 7:
+#line 177 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_symbol_cluster); }}
         break;
-        case 19:
-#line 176 "hb-ot-shaper-use-machine.rl"
+        case 21:
+#line 178 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
         break;
-        case 17:
-#line 177 "hb-ot-shaper-use-machine.rl"
+        case 19:
+#line 179 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
         break;
-        case 18:
-#line 178 "hb-ot-shaper-use-machine.rl"
+        case 20:
+#line 180 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_non_cluster); }}
         break;
-#line 1014 "hb-ot-shaper-use-machine.hh"
+        case 1:
+#line 177 "hb-ot-shaper-use-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (use_symbol_cluster); }}
+        break;
+#line 1049 "hb-ot-shaper-use-machine.hh"
         }
 
 _again:
         switch ( _use_syllable_machine_to_state_actions[cs] ) {
-        case 1:
+        case 2:
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 1021 "hb-ot-shaper-use-machine.hh"
+#line 1058 "hb-ot-shaper-use-machine.hh"
         }
 
         if ( ++p != pe )
@@ -1071,7 +1070,7 @@
 
         }
 
-#line 287 "hb-ot-shaper-use-machine.rl"
+#line 289 "hb-ot-shaper-use-machine.rl"
 
 }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -6,18 +6,18 @@
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # IndicPositionalCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # DerivedCoreProperties-15.0.0.txt
- * # Date: 2022-08-05, 22:17:05 GMT
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
+ * # IndicSyllabicCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # IndicPositionalCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # ArabicShaping-15.1.0.txt
+ * # Date: 2023-01-05
+ * # DerivedCoreProperties-15.1.0.txt
+ * # Date: 2023-08-07, 15:21:24 GMT
+ * # Blocks-15.1.0.txt
+ * # Date: 2023-07-28, 15:47:20 GMT
+ * # Scripts-15.1.0.txt
+ * # Date: 2023-07-28, 16:01:07 GMT
  * # Override values For Indic_Syllabic_Category
  * # Not derivable
  * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
@@ -26,6 +26,7 @@
  * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
  * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25
  * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
+ * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14
  * # Override values For Indic_Positional_Category
  * # Not derivable
  * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
@@ -36,6 +37,7 @@
  * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
  * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28
  * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
+ * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14
  * UnicodeData.txt does not have a header.
  */
 
@@ -54,7 +56,9 @@
 #define G       USE(G)  /* HIEROGLYPH */
 #define GB      USE(GB) /* BASE_OTHER */
 #define H       USE(H)  /* HALANT */
+#define HM      USE(HM) /* HIEROGLYPH_MOD */
 #define HN      USE(HN) /* HALANT_NUM */
+#define HR      USE(HR) /* HIEROGLYPH_MIRROR */
 #define HVM     USE(HVM)        /* HALANT_OR_VOWEL_MODIFIER */
 #define IS      USE(IS) /* INVISIBLE_STACKER */
 #define J       USE(J)  /* HIEROGLYPH_JOINER */
@@ -95,7 +99,7 @@
 #ifndef HB_OPTIMIZE_SIZE
 
 static const uint8_t
-hb_use_u8[3141] =
+hb_use_u8[3187] =
 {
      16,   50,   51,   51,   51,   52,   51,   83,  118,  131,   51,   57,   58,  179,  195,   61,
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
@@ -109,244 +113,249 @@
      18,   19,   20,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   21,
      22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,    2,   33,    2,    2,    2,
       2,   34,   35,    2,    2,    2,    2,    2,    2,    2,    2,    2,   36,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   37,    2,    2,    2,    2,
+     37,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   38,    2,   39,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,   38,   39,   40,   41,   42,   43,    2,   44,    2,    2,    2,    2,    2,    2,    2,
+      2,   40,   41,   42,   43,   44,   45,    2,   46,    2,    2,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   45,   46,    2,
-     47,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   48,   49,    2,    2,    2,
-      2,    2,    2,    2,    2,   50,   51,    2,   52,    2,    2,   53,    2,    2,   54,   55,
-     56,   57,   58,   59,   60,   61,   62,   63,    2,   64,   65,    2,   66,   67,   68,   69,
-      2,   70,    2,   71,   72,   73,   74,    2,    2,   75,   76,   77,   78,    2,   79,   80,
-      2,   81,   81,   81,   81,   81,   81,   81,   81,   82,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   47,   48,    2,
+     49,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   50,   51,    2,    2,    2,
+      2,    2,    2,    2,    2,   52,   53,    2,   54,    2,    2,   55,    2,    2,   56,   57,
+     58,   59,   60,   61,   62,   63,   64,   65,    2,   66,   67,    2,   68,   69,   70,   71,
+      2,   72,    2,   73,   74,   75,   76,    2,    2,   77,   78,   79,   80,    2,   81,   82,
+      2,   83,   83,   83,   83,   83,   83,   83,   83,   84,    2,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,   83,   84,    2,    2,    2,    2,    2,    2,    2,   85,
-     86,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,   81,   81,   81,   87,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,   85,   86,    2,    2,    2,    2,    2,    2,    2,   87,
+     88,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,   89,   89,   89,   90,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    2,   88,   89,    2,    2,    2,    2,    2,
-      2,    2,    2,   90,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    2,   91,   92,    2,    2,    2,    2,    2,
+      2,    2,    2,   93,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,   91,    2,    2,   92,    2,    2,    2,   93,    2,    2,    2,    2,    2,
-      2,    2,    2,   94,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,   95,   95,   96,   97,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
-     95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
-     95,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
-      0,    2,    2,    2,    2,    2,    0,    0,    0,    3,    0,    0,    0,    0,    0,    4,
-      0,    0,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    8,    9,    9,    9,    9,    0,    0,    0,    7,   10,
-      0,    2,    2,    2,    2,   11,   12,    0,    0,    9,   13,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,   14,   15,   16,   17,   18,   19,   20,   14,   21,   22,
-     23,   10,   24,   25,   18,    2,    2,    2,    2,    2,   18,    0,    2,    2,    2,    2,
-      2,    0,    2,    2,    2,    2,    2,    2,    2,   26,   27,   28,    2,    2,    2,    7,
-     28,    7,   28,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    7,    2,    2,
-      2,    7,    7,    0,    2,    2,    0,   15,   16,   17,   18,   29,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    2,   28,    2,    0,    0,    0,    0,    0,    7,
-     34,   10,   13,   28,    2,    2,    7,    0,   28,    7,    2,   28,    7,    2,    0,   35,
-     16,   17,   29,    0,   25,   36,   25,   37,    0,   38,    0,    0,    0,   28,    2,    7,
-      7,    0,    0,    0,    2,    2,    2,    2,    2,   39,   40,   41,    0,    0,    0,    0,
-      0,   10,   13,   28,    2,    2,    2,    2,   28,    2,   28,    2,    2,    2,    2,    2,
-      2,    7,    2,   28,    2,    2,    0,   15,   16,   17,   18,   19,   25,   20,   33,   22,
-      0,    0,    0,    0,    0,   28,   39,   39,   42,   10,   27,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,    0,   15,   43,    0,    0,   25,   20,    0,    0,    2,
-     28,   28,    0,    0,    0,    0,    0,    0,    0,    0,   44,   28,    2,    2,    7,    0,
-      2,    7,    2,    2,    0,   28,    7,    7,    2,    0,   28,    7,    0,    2,    7,    0,
-      2,    2,    2,    2,    2,    2,    0,    0,   21,   14,   45,    0,   46,   31,   46,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    0,   13,   27,   47,    2,    2,    2,    7,
-      2,    7,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,   15,
-     20,   14,   21,   45,   20,   36,   20,   37,    0,    0,    0,   25,   29,    2,    7,    0,
-      0,    8,   27,   28,    2,    2,    2,    7,    2,    2,    2,   28,    2,    2,    0,   15,
-     43,    0,    0,   33,   45,    0,    0,    0,    7,   48,   49,    0,    0,    0,    0,    0,
-      0,    9,   27,    2,    2,    2,    2,    7,    2,    2,    2,    2,    2,    2,   50,   51,
-     21,   21,   17,   29,   46,   31,   46,   32,   52,    0,    0,    0,   33,    0,    0,    0,
-     28,   10,   27,   28,    2,    2,    2,    2,    2,    2,    2,    2,    7,    0,    2,    2,
-      2,    2,   28,    2,    2,    2,    2,   28,    0,    2,    2,    2,    7,    0,   53,    0,
-     33,   21,   20,   29,   29,   16,   46,   46,   23,    0,   21,    0,    0,    0,    0,    0,
-      0,    2,    0,    2,    7,    0,    0,    0,    0,    0,    0,    0,    0,   18,    0,    0,
-      0,    2,    2,   54,   54,   55,    0,    0,   16,    2,    2,    2,    2,   28,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    7,    0,   56,   19,   57,   20,   20,   18,   18,
-     44,   19,    9,   29,    9,    2,    2,   58,   59,   59,   59,   59,   59,   60,   59,   59,
-     59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   61,
-      0,    0,    0,    0,   62,    0,    0,    0,    0,    2,    2,    2,    2,    2,   63,   43,
-     57,   64,   20,   20,   65,   66,   67,   68,   69,    2,    2,    2,    2,    2,    1,    0,
-      3,    2,    2,    2,   21,   18,    2,    2,   70,   69,   71,   72,   63,   71,   27,   27,
-      2,   50,   20,   51,    2,    2,    2,    2,    2,    2,   73,   74,   75,   27,   27,   76,
-     77,    2,    2,    2,    2,    2,   27,   43,    0,    2,   57,   78,    0,    0,    0,    0,
-     28,    2,   57,   45,    0,    0,    0,    0,    0,    2,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,    7,    2,    7,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,   79,   43,   20,   57,   18,   46,   46,   46,   46,   13,   80,   81,   82,
-     83,   84,   85,    0,    0,    0,    0,   86,    0,    7,    0,    0,   28,    0,   87,   79,
-     88,    2,    2,    2,    2,    7,    0,    0,    0,   40,   40,   89,   90,    2,    2,    2,
-      2,    2,    2,    2,    2,   11,    7,    0,    0,   91,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    7,   20,   78,   43,   20,   92,   59,    0,
-      0,   93,   94,   93,   93,   95,   96,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-      0,    2,    2,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    0,
-      0,    2,    2,    2,    2,   27,    0,    0,    0,    2,    2,    2,    2,    2,    7,    0,
-      0,    2,    2,    2,   50,   97,   43,    0,    0,    2,    2,   98,   99,  100,  101,   59,
-     61,  102,   14,   43,   20,   57,   19,   78,   46,   46,   74,    9,    9,    9,  103,   44,
-     38,    9,  104,   72,    2,    2,    2,    2,    2,    2,    2,  105,   20,   18,   18,   20,
-     46,   46,   20,  106,    2,    2,    2,    7,    0,    0,    0,    0,    0,    0,  107,  108,
-    109,  109,  109,    0,    0,    0,    0,    0,    0,  104,   72,    2,    2,    2,    2,    2,
-      2,   58,   59,   57,   23,   20,  110,   59,    2,    2,    2,    2,  105,   20,   21,   43,
-     43,  100,   12,    0,    0,    0,    0,    0,    0,    2,    2,   59,   16,   46,   21,  111,
-    100,  100,  100,  112,  113,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   28,
-      2,    9,   44,  114,  114,  114,    9,  114,  114,   13,  114,  114,  114,   24,    0,   38,
-      0,    0,    0,  115,   49,    9,    3,    0,    0,    0,    0,    0,    0,    0,  116,    0,
-      0,    0,    0,    0,    0,    0,    4,  117,  118,   40,   40,    3,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,  118,  118,  119,  118,  118,  118,  118,  118,  118,  118,
-    118,    0,    0,  120,    0,    0,    0,    0,    0,    0,    5,  120,    0,    0,    0,    0,
-      0,   44,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    7,
-      0,    2,    2,    2,    2,    0,    0,    0,   28,    0,    0,    0,    0,    0,    0,    0,
-    121,    2,   51,    2,  106,    2,    8,    2,    2,    2,   63,   17,   14,    0,    0,   29,
-      0,    2,    2,    0,    0,    0,    0,    0,    0,   27,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,  122,   21,   21,   21,   21,   21,   21,   21,  123,    0,    0,    0,    0,
-      0,    9,    9,    9,    9,    9,    9,    9,    9,    9,    2,    0,    0,    0,    0,    0,
-     50,    2,    2,    2,   20,   20,  124,  114,    0,    2,    2,    2,  125,   18,   57,   18,
-    111,  100,  126,    0,    0,    0,    0,    0,    0,    9,  127,    2,    2,    2,    2,    2,
-      2,    2,  128,   21,   20,   18,   46,  129,  130,  131,    0,    0,    0,    0,    0,    0,
-      0,    2,    2,   50,   28,    2,    2,    2,    2,    2,    2,    2,    2,    8,   20,   57,
-     97,   74,  132,  133,  134,    0,    0,    0,    0,    2,  135,    2,    2,    2,    2,  136,
-      0,   28,    2,   40,    3,    0,   77,   13,    2,   51,   20,  137,   50,   51,    2,    2,
-    103,    8,    7,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  138,   19,
-     23,    0,    0,  139,  140,    0,    0,    0,    0,    2,   63,   43,   21,   78,   45,  141,
-      0,   79,   79,   79,   79,   79,   79,   79,   79,    0,    0,    0,    0,    0,    0,    0,
-      4,  118,  118,  118,  118,  119,    0,    0,    0,    2,    2,    2,    2,    2,    7,    2,
-      2,    2,    7,    2,   28,    2,    2,    2,    2,    2,   28,    2,    2,    2,   28,    7,
-      0,  125,   18,   25,   29,    0,    0,  142,  143,    2,    2,   28,    2,   28,    2,    2,
-      2,    2,    2,    2,    0,   12,   35,    0,  144,    2,    2,   11,   35,    0,   28,    2,
-      2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   28,    2,    2,
-      7,    2,    2,    9,   39,    0,    0,    0,    0,    2,    2,    2,    2,    2,   25,   36,
-      0,    2,    2,    2,  114,  114,  114,  114,  114,  145,    2,    7,    0,    0,    0,    0,
-      0,    2,   12,   12,    0,    0,    0,    0,    0,    7,    2,    2,    7,    2,    2,    2,
-      2,   28,    2,    7,    0,   28,    2,    0,    0,  146,  147,  148,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,   20,   20,   18,   18,   18,   20,   20,  131,    0,    0,    0,
-      0,    0,  149,  149,  149,  149,  149,  149,  149,  149,  149,  149,    2,    2,    2,    2,
-      2,   51,   50,   51,    0,    0,    0,    0,  150,    9,   72,    2,    2,    2,    2,    2,
-      2,   16,   17,   19,   14,   22,   35,    0,    0,    0,   29,    0,    0,    0,    0,    0,
-      0,    9,   47,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   18,   20,  151,
-     20,   19,  152,  153,    2,    2,    2,    2,    2,    0,    0,   63,  154,    0,    0,    0,
-      0,    2,   11,    0,    0,    0,    0,    0,    0,    2,   63,   23,   18,   18,   18,   20,
-     20,  106,  155,    0,    0,   54,  156,   29,  157,   28,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,   21,   17,   20,   20,  158,   42,    0,    0,    0,
-     47,  125,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    7,    7,    2,    2,
-     28,    2,    2,    2,    2,    2,    2,    2,   28,    2,    2,    2,    2,    2,    2,    2,
-      8,   16,   17,   19,   20,  159,   29,    0,    0,    9,    9,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,   56,   15,   21,   14,   21,   45,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    2,    2,   21,    0,    9,    9,    9,   44,
-      0,    9,    9,   44,    0,    0,    0,    0,    0,    2,    2,   63,   23,   18,   18,   18,
-     20,   21,  123,   13,   15,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
-    160,  161,    0,    0,    0,    0,    0,    0,    0,   16,   17,   18,   18,   64,   97,   23,
-    157,    9,  162,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-     63,   23,   18,   18,    0,   46,   46,    9,  163,   35,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    2,    2,   18,    0,   21,   17,   18,   18,   19,   14,   80,
-    163,   36,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    8,  164,
-     23,   18,   20,   20,  162,    7,    0,    0,    0,    2,    2,    2,    2,    2,    7,   41,
-    133,   21,   20,   18,   74,   19,   20,    0,    0,    2,    2,    2,    7,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,   16,   17,   18,   19,   20,  103,  163,   35,    0,
-      0,    2,    2,    2,    7,   28,    0,    2,    2,    2,    2,   28,    7,    2,    2,    2,
-      2,   21,   21,   16,   30,   31,   10,  165,  166,  167,  168,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    0,    2,    2,    2,   63,   23,   18,   18,    0,   20,   21,
-     27,  106,    0,   31,    0,    0,    0,    0,    0,   50,   18,   20,   20,   20,  137,    2,
-      2,    2,  169,  170,    9,   13,  171,   70,  172,    0,    0,    1,  144,    0,    0,    0,
-      0,   50,   18,   20,   14,   17,   18,    2,    2,    2,    2,  155,  155,  155,  173,  173,
-    173,  173,  173,  173,   13,  174,    0,   28,    0,   20,   18,   18,   29,   20,   20,    9,
-    163,    0,   59,   59,   59,   59,   59,   59,   59,   64,   19,   80,   44,    0,    0,    0,
-      0,    2,    2,    2,    7,    2,   28,    2,    2,   50,   20,   20,   29,    0,   36,   20,
-     25,    9,  156,  175,  171,    0,    0,    0,    0,    2,    2,    2,   28,    7,    2,    2,
-      2,    2,    2,    2,    2,    2,   21,   21,   45,   20,   33,   80,   66,    0,    0,    0,
-      0,    2,  176,   64,   45,    0,    0,    0,    0,    9,  177,    2,    2,    2,    2,    2,
-      2,    2,    2,   21,   20,   18,   29,    0,   46,   14,  140,    0,    0,    0,    0,    0,
-      0,  178,  178,  178,  106,  179,  178,    0,    0,  145,    2,    2,  180,  114,  114,  114,
-    114,  114,  114,  114,    0,    0,    0,    0,    0,    9,    9,    9,   44,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    7,    0,   56,  181,   18,   18,   18,   18,   18,   18,
-     18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,    0,    0,    0,
-     38,  114,   24,    0,    0,    0,    0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
-      0,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   56,
-     35,    0,    4,  118,  118,  118,  119,    0,    0,    9,    9,    9,   47,    2,    2,    2,
+      2,    2,    2,   94,    2,    2,   95,    2,    2,    2,   96,    2,    2,    2,    2,    2,
+      2,    2,    2,   97,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      2,   98,   98,   99,  100,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
+     98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
+     98,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
+      0,    2,    2,    2,    2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    3,    4,
+      0,    5,    0,    0,    0,    0,    0,    6,    0,    0,    7,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      8,    9,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   10,   11,
+     11,   11,   11,    0,    0,    0,    9,   12,    0,    2,    2,    2,    2,   13,   14,    0,
+      0,   11,   15,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   16,   17,
+     18,   19,   20,   21,   22,   16,   23,   24,   25,   12,   26,   27,   20,    2,    2,    2,
+      2,    2,   20,    0,    2,    2,    2,    2,    2,    0,    2,    2,    2,    2,    2,    2,
+      2,   28,   29,   30,    2,    2,    2,    9,   30,    9,   30,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    9,    2,    2,    2,    9,    9,    0,    2,    2,    0,   17,
+     18,   19,   20,   31,   32,   33,   32,   34,    0,    0,    0,    0,   35,    0,    0,    2,
+     30,    2,    0,    0,    0,    0,    0,    9,   36,   12,   15,   30,    2,    2,    9,    0,
+     30,    9,    2,   30,    9,    2,    0,   37,   18,   19,   31,    0,   27,   38,   27,   39,
+      0,   40,    0,    0,    0,   30,    2,    9,    9,    0,    0,    0,    2,    2,    2,    2,
+      2,   41,   42,   43,    0,    0,    0,    0,    0,   12,   15,   30,    2,    2,    2,    2,
+     30,    2,   30,    2,    2,    2,    2,    2,    2,    9,    2,   30,    2,    2,    0,   17,
+     18,   19,   20,   21,   27,   22,   35,   24,    0,    0,    0,    0,    0,   30,   41,   41,
+     44,   12,   29,   30,    2,    2,    2,    9,   30,    9,    2,   30,    2,    2,    0,   17,
+     45,    0,    0,   27,   22,    0,    0,    2,   30,   30,    0,    0,    0,    0,    0,    0,
+      0,    0,   46,   30,    2,    2,    9,    0,    2,    9,    2,    2,    0,   30,    9,    9,
+      2,    0,   30,    9,    0,    2,    9,    0,    2,    2,    2,    2,    2,    2,    0,    0,
+     23,   16,   47,    0,   48,   33,   48,   34,    0,    0,    0,    0,   35,    0,    0,    0,
+      0,   15,   29,   49,    2,    2,    2,    9,    2,    9,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    0,   17,   22,   16,   23,   47,   22,   38,   22,   39,
+      0,    0,    0,   27,   31,    2,    9,    0,    0,   10,   29,   30,    2,    2,    2,    9,
+      2,    2,    2,   30,    2,    2,    0,   17,   45,    0,    0,   35,   47,    0,    0,    0,
+      9,   50,   51,    0,    0,    0,    0,    0,    0,   11,   29,    2,    2,    2,    2,    9,
+      2,    2,    2,    2,    2,    2,   52,   53,   23,   23,   19,   31,   48,   33,   48,   34,
+     54,    0,    0,    0,   35,    0,    0,    0,   30,   12,   29,   30,    2,    2,    2,    2,
+      2,    2,    2,    2,    9,    0,    2,    2,    2,    2,   30,    2,    2,    2,    2,   30,
+      0,    2,    2,    2,    9,    0,   55,    0,   35,   23,   22,   31,   31,   18,   48,   48,
+     25,    0,   23,    0,    0,    0,    0,    0,    0,    2,    0,    2,    9,    0,    0,    0,
+      0,    0,    0,    0,    0,   20,    0,    0,    0,    2,    2,   56,   56,   57,    0,    0,
+     18,    2,    2,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    9,
+      0,   58,   21,   59,   22,   22,   20,   20,   46,   21,   11,   31,   11,    2,    2,   60,
+     61,   61,   61,   61,   61,   62,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,
+     61,   61,   61,   61,   61,   61,   61,   63,    0,    0,    0,    0,   64,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   65,   45,   59,   66,   22,   22,   67,   68,   69,   70,
+     71,    2,    2,    2,    2,    2,    1,    0,    5,    2,    2,    2,   23,   20,    2,    2,
+     72,   71,   73,   74,   65,   73,   29,   29,    2,   52,   22,   53,    2,    2,    2,    2,
+      2,    2,   75,   76,   77,   29,   29,   78,   79,    2,    2,    2,    2,    2,   29,   45,
+      0,    2,   59,   80,    0,    0,    0,    0,   30,    2,   59,   47,    0,    0,    0,    0,
+      0,    2,   59,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    9,
+      2,    9,   59,    0,    0,    0,    0,    0,    0,    2,    2,   81,   45,   22,   59,   20,
+     48,   48,   48,   48,   15,   82,   83,   84,   85,   86,   87,    0,    0,    0,    0,   88,
+      0,    9,    0,    0,   30,    0,   89,   81,   90,    2,    2,    2,    2,    9,    0,    0,
+      0,   42,   42,   91,   92,    2,    2,    2,    2,    2,    2,    2,    2,   13,    9,    0,
+      0,   93,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      9,   22,   80,   45,   22,   94,   61,    0,    0,   95,   96,   95,   95,   97,   98,    0,
+      0,    2,    2,    2,    2,    2,    2,    2,    0,    2,    2,    9,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,   29,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,    0,    0,    2,    2,    2,   52,   99,   45,    0,
+      0,    2,    2,  100,  101,  102,  103,   61,   63,  104,   16,   45,   22,   59,   21,   80,
+     48,   48,   76,   11,   11,   11,  105,   46,   40,   11,  106,   74,    2,    2,    2,    2,
+      2,    2,    2,  107,   22,   20,   20,   22,   48,   48,   22,  108,    2,    2,    2,    9,
+      0,    0,    0,    0,    0,    0,  109,  110,  111,  111,  111,    0,    0,    0,    0,    0,
+      0,  106,   74,    2,    2,    2,    2,    2,    2,   60,   61,   59,   25,   22,  112,   61,
+      2,    2,    2,    2,  107,   22,   23,   45,   45,  102,   14,    0,    0,    0,    0,    0,
+      0,    2,    2,   61,   18,   48,   23,  113,  102,  102,  102,  114,  115,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,   30,    2,   11,   46,  116,  116,  116,   11,  116,
+    116,   15,  116,  116,  116,   26,    0,   40,    0,    0,    0,  117,   51,   11,    5,    0,
+      0,    0,    0,    0,    0,    0,  118,    0,    0,    0,    0,    0,    0,    0,    6,  119,
+    120,   42,   42,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  120,  120,
+    121,  120,  120,  120,  120,  120,  120,  120,  120,    0,    0,  122,    0,    0,    0,    0,
+      0,    0,    7,  122,    0,    0,    0,    0,    0,   46,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,  123,  123,    0,    0,
+      0,    2,    2,    2,    2,    0,    0,    0,   30,    0,    0,    0,    0,    0,    0,    0,
+    124,    0,  123,  123,    0,    0,    0,    0,    0,    2,   53,    2,  108,    2,   10,    2,
+      2,    2,   65,   19,   16,    0,    0,   31,    0,    2,    2,    0,    0,    0,    0,    0,
+      0,   29,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   23,   23,   23,   23,
+     23,   23,   23,  126,    0,    0,    0,    0,    0,   11,   11,   11,   11,   11,   11,   11,
+     11,   11,    2,    0,    0,    0,    0,    0,   52,    2,    2,    2,   22,   22,  127,  116,
+      0,    2,    2,    2,  128,   20,   59,   20,  113,  102,  129,    0,    0,    0,    0,    0,
+      0,   11,  130,    2,    2,    2,    2,    2,    2,    2,  131,   23,   22,   20,   48,  132,
+    133,  134,    0,    0,    0,    0,    0,    0,    0,    2,    2,   52,   30,    2,    2,    2,
+      2,    2,    2,    2,    2,   10,   22,   59,   99,   76,  135,  136,  137,    0,    0,    0,
+      0,    2,  138,    2,    2,    2,    2,  139,    0,   30,    2,   42,    5,    0,   79,   15,
+      2,   53,   22,  140,   52,   53,    2,    2,  105,   10,    9,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,  141,   21,   25,    0,    0,  142,  143,    0,    0,    0,
+      0,    2,   65,   45,   23,   80,   47,  144,    0,   81,   81,   81,   81,   81,   81,   81,
+     81,    0,    0,    0,    0,    0,    0,    0,    6,  120,  120,  120,  120,  121,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,    2,    2,    2,    9,    2,   30,    2,    2,    2,
+      2,    2,   30,    2,    2,    2,   30,    9,    0,  128,   20,   27,   31,    0,    0,  145,
+    146,    2,    2,   30,    2,   30,    2,    2,    2,    2,    2,    2,    0,   14,   37,    0,
+    147,    2,    2,   13,   37,    0,   30,    2,    2,    2,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,   30,    2,    2,    9,    2,    2,   11,   41,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   27,   38,    0,    2,    2,    2,  116,  116,  116,  116,
+    116,  148,    2,    9,    0,    0,    0,    0,    0,    2,   14,   14,    0,    0,    0,    0,
+      0,    9,    2,    2,    9,    2,    2,    2,    2,   30,    2,    9,    0,   30,    2,    0,
+      0,  149,  150,  151,    2,    2,    2,    2,    2,    2,    2,    2,    2,   22,   22,   20,
+     20,   20,   22,   22,  134,    0,    0,    0,    0,    0,  152,  152,  152,  152,  152,  152,
+    152,  152,  152,  152,    2,    2,    2,    2,    2,   53,   52,   53,    0,    0,    0,    0,
+    153,   11,   74,    2,    2,    2,    2,    2,    2,   18,   19,   21,   16,   24,   37,    0,
+      0,    0,   31,    0,    0,    0,    0,    0,    0,   11,   49,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,  128,   20,   22,  154,   22,   21,  155,  156,    2,    2,    2,    2,
+      2,    0,    0,   65,  157,    0,    0,    0,    0,    2,   13,    0,    0,    0,    0,    0,
+      0,    2,   65,   25,   20,   20,   20,   22,   22,  108,  158,    0,    0,   56,  159,   31,
+    160,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   23,
+     19,   22,   22,  161,   44,    0,    0,    0,   49,  128,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    9,    9,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,
+     30,    2,    2,    2,    2,    2,    2,    2,   10,   18,   19,   21,   22,  162,   31,    0,
+      0,   11,   11,   30,    2,    2,    2,    9,   30,    9,    2,   30,    2,    2,   58,   17,
+     23,   16,   23,   47,   32,   33,   32,   34,    0,    0,    0,    0,   35,    0,    0,    0,
+      2,    2,   23,    0,   11,   11,   11,   46,    0,   11,   11,   46,    0,    0,    0,    0,
+      0,    2,    2,   65,   25,   20,   20,   20,   22,   23,  126,   15,   17,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,    0,  163,  164,    0,    0,    0,    0,    0,    0,
+      0,   18,   19,   20,   20,   66,   99,   25,  160,   11,  165,    9,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,    2,   65,   25,   20,   20,    0,   48,   48,   11,
+    166,   37,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,    2,   20,
+      0,   23,   19,   20,   20,   21,   16,   82,  166,   38,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   10,  167,   25,   20,   22,   22,  165,    9,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,   43,  136,   23,   22,   20,   76,   21,   22,    0,
+      0,    2,    2,    2,    9,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,   18,
+     19,   20,   21,   22,  105,  166,   37,    0,    0,    2,    2,    2,    9,   30,    0,    2,
+      2,    2,    2,   30,    9,    2,    2,    2,    2,   23,   23,   18,   32,   33,   12,  168,
+    169,  170,  171,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    0,    2,    2,
+      2,   65,   25,   20,   20,    0,   22,   23,   29,  108,    0,   33,    0,    0,    0,    0,
+      0,   52,   20,   22,   22,   22,  140,    2,    2,    2,  172,  173,   11,   15,  174,   72,
+    175,    0,    0,    1,  147,    0,    0,    0,    0,   52,   20,   22,   16,   19,   20,    2,
+      2,    2,    2,  158,  158,  158,  176,  176,  176,  176,  176,  176,   15,  177,    0,   30,
+      0,   22,   20,   20,   31,   22,   22,   11,  166,    0,   61,   61,   61,   61,   61,   61,
+     61,   66,   21,   82,   46,    0,    0,    0,    0,    2,    2,    2,    9,    2,   30,    2,
+      2,   52,   22,   22,   31,    0,   38,   22,   27,   11,  159,  178,  174,    0,    0,    0,
+      0,    2,    2,    2,   30,    9,    2,    2,    2,    2,    2,    2,    2,    2,   23,   23,
+     47,   22,   35,   82,   68,    0,    0,    0,    0,    2,  179,   66,   47,    0,    0,    0,
+      0,   11,  180,    2,    2,    2,    2,    2,    2,    2,    2,   23,   22,   20,   31,    0,
+     48,   16,  143,    0,    0,    0,    0,    0,    0,  181,  181,  181,  181,  181,  181,  181,
+    181,  182,  182,  182,  183,  184,  182,  181,  181,  185,  181,  181,  186,  187,  187,  187,
+    187,  187,  187,  187,    0,    0,    0,    0,    0,   11,   11,   11,   46,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,    0,   58,  188,   20,   20,   20,   20,   20,   20,
+     20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,    0,    0,    0,
+     40,  116,   26,    0,    0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,
+      0,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   58,
+     37,    0,    6,  120,  120,  120,  121,    0,    0,   11,   11,   11,   49,    2,    2,    2,
       0,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,
-     44,    2,    2,    2,    2,    2,    2,    9,    9,    2,    2,    2,    2,    2,    2,   20,
-     20,    2,    2,   42,   42,   42,   90,    0,    0,    O,    O,    O,   GB,    B,    B,   GB,
-      O,    O,   WJ,FMPst,FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,VMAbv,    O,VMAbv,    B,
-  CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
-   VAbv, VAbv, VAbv, VPst, VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O, VAbv,   GB,VMAbv,VMPst,
-  VMPst,    O,    B, VBlw,    O,    O, VPre, VPre,    O, VPre,    H,    O, VPst,FMAbv,    O,CMBlw,
-      O, VAbv,    O, VAbv,    H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O, MBlw,CMAbv,CMAbv, VPst,
-   VAbv,VMAbv,    O, VPst,    O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,VMPst,    B, VAbv, VAbv,
-      B,    R,    O,  HVM,    O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv, VBlw,    B,  SUB,  SUB,
-    SUB,    O,  SUB,  SUB,    O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst,   IS, VAbv,
-   MPst, MPre, MBlw, MBlw,    B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw, VPst, VPre, VAbv, VAbv,
-  VMPst,VMPst,VMBlw,    B,VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
-  VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,
-      B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,
-    SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,
-  SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
-     CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,    O,    H, MPst, VPst,    H,
-  VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,
-      O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,
-  VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,
-     CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,
-      R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,
-      H,VMPst, VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,    R,
-   MBlw, MBlw,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB, VAbv,    R,VMPst,    H,    H,    B,
-      H,    B,VMBlw,    O, VBlw,
+     46,    2,    2,    2,    2,    2,    2,   11,   11,    2,    2,    2,    2,    2,    2,   22,
+     22,    2,    2,   44,   44,   44,   92,    0,    0,    O,    O,    O,   GB,    B,    B,    O,
+     SB,    O,   SE,   GB,    O,    O,   WJ,FMPst,FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,
+  VMAbv,    O,VMAbv,    B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst,
+   VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O,
+   VAbv,   GB,VMAbv,VMPst,VMPst,    O,    B, VBlw,    O,    O, VPre, VPre,    O, VPre,    H,    O,
+   VPst,FMAbv,    O,CMBlw,    O, VAbv,    O, VAbv,    H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O,
+   MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv,    O, VPst,    O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,
+  VMPst,    B, VAbv, VAbv,    B,    R,    O,  HVM,    O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv,
+   VBlw,    B,  SUB,  SUB,  SUB,    O,  SUB,  SUB,    O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,
+  VMBlw,VMPst,   IS, VAbv, MPst, MPre, MBlw, MBlw,    B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw,
+   VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw,    B,VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,
+  FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,
+  CMAbv,CMAbv,    B,   GB,    B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv,
+   VPre,    B, MPre, MBlw,  SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv,
+   VPst,    H,    B,    O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,
+  CMBlw,VMBlw,VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,   SB,
+     SE,    O,    H, MPst, VPst,    H,VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,
+  CMAbv, VAbv, MBlw, MPst, MBlw,    H,    O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv,
+   FPst, VBlw,    B,    B, VPre,    O,VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,
+     IS,VMBlw,    B,VMPst,VMAbv,VMPst,   CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,
+     IS,CMAbv,    O, VPst,    B,    R,    R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,
+      B,   CS,   CS,    H,CMBlw,VMPst,    H,VMPst, VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,
+  CMBlw,    B,FMBlw, VBlw,VMAbv,    R, MBlw, MBlw,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB,
+   VAbv,    R,VMPst,    G,    G,    J,    J,    J,   SB,   SE,    J,   HR,    G,    G,   HM,   HM,
+     HM,    O, VBlw,
 };
 static const uint16_t
-hb_use_u16[784] =
+hb_use_u16[808] =
 {
-    0,  0,  1,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  5,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,
-    0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  8,  9, 10, 11,
-    0,  0,  0,  0,  9, 12,  0,  0, 13,  9,  9, 14, 15, 16, 17, 18,
-   19, 20, 21, 22, 23, 24, 17, 25, 26, 20, 21, 27, 28, 29, 30, 31,
-   32, 33, 21, 34, 35,  0, 17, 36, 37, 20, 21, 38, 23, 39, 17, 40,
-   41, 42, 43, 44, 45, 46, 30,  0, 47, 48, 21, 49, 50, 51, 17,  0,
-   52, 48, 21, 53, 50, 54, 17, 55, 56, 48,  9, 57, 58, 59, 17,  0,
-   60, 61,  9, 62, 63, 64, 30, 65, 66, 67,  9, 68, 69,  9, 70, 71,
-   72, 73, 74, 75, 76,  0,  0,  0,  9,  9, 77, 78, 79, 80, 81, 82,
-   83, 84,  0,  0,  0,  0,  0,  0,  9, 85,  9, 86,  9, 87, 88, 89,
-    9,  9,  9, 90, 91, 92,  2,  0, 93,  0,  9,  9,  9,  9,  9, 94,
-   95,  9, 96,  0,  0,  0,  0,  0, 97, 98, 99,100, 30,  9,101,102,
-    9,  9,103,  9,104,105,  0,  0,  9,106,  9,  9,  9,107,108,109,
-    2,  2,  0,  0,  0,  0,  0,  0,110,  9,  9,111,112,  2,113,114,
-  115,  9,116,  9,  9,  9,117,118,  9,  9,119,120,121,  0,  0,  0,
-    0,  0,  0,  0,  0,122,123,124,  0,  0,  0,  0,  0,  0,  0,125,
-  126,127,128,  0,  0,  0,129,130,131,  0,  0,  0,  0,  0,  0,132,
-    0,  0,  0,  0,133,  0,  0,  0,  0,  0,  0,  9,  9,  9,134,135,
-  136,  9,137,  0,  9,  9,  9,138,139,  9,  9,140,141,  2,142,143,
-    9,  9,144,  9,145,146,  0,  0,147,  9,  9,148,149,  2,150, 98,
-    9,  9,151,152,153,  2,  9,154,  9,  9,  9,155,156,  0,157,158,
-    0,  0,  0,  0,  9,  9,159,  2,160,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,161,  0,  0,  0,  0,  0,  0,  0,162,
-    0,  0,  0,  0,  0,  0,  0,163,163,164, 33,165,  0,  0,  0,  0,
-  166,167,  9,168, 94,  0,  0,  0,  0,  0,  0,  0, 69,  9,169,  0,
-    9,170,171,  0,  0,  0,  0,  0,  9,  9,172,  2,  0,  0,  0,  0,
-    9,  9,173,170,  0,  0,  0,  0,  0,  0,  0,  9,174,175,  0,  9,
-  176,  0,  0,177,178,  0,  0,  0,179,  9,  9,180,181,182,183,184,
-  185,  9,  9,186,187,  0,  0,  0,188,  9,189,190,191,  9,  9,192,
-  185,  9,  9,193,194,105,195,102,  9, 33,196,197,198,  0,  0,  0,
-  199,200, 94,  9,  9,201,202,  2,203, 20, 21,204,205,206,207,208,
-    9,  9,  9,209,210,211,212,  0,195,  9,  9,213,214,  2,  0,  0,
-    9,  9,215,216,217,218,  0,  0,  9,  9,  9,219,220,  2,  0,  0,
-    9,  9,221,222,  2,  0,  0,  0,  9,223,224,103,225,  0,  0,  0,
-    9,  9,226,227,  0,  0,  0,  0,228,229,  9,230,231,  2,  0,  0,
-    0,  0,232,  9,  9,233,234,  0,235,  9,  9,236,237,238,  9,  9,
-  239,240,  0,  0,  0,  0,  0,  0, 21,  9,215,241,  7,  9, 70, 18,
-    9,242, 73,243,  0,  0,  0,  0,244,  9,  9,245,246,  2,247,  9,
-  248,249,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,250,
-  251, 48,  9,252,253,  2,  0,  0,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,254,255,256,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,
-    9,  9,  9,257,  0,  0,  0,  0,  9,  9,  9,  9,258,259,260,260,
-  261,262,  0,  0,  0,  0,263,  0,  9,  9,  9,  9,  9,264,  0,  0,
-    9,  9,  9,  9,  9,  9,105, 70, 94,265,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,266,  9,  9, 70,267,268,  0,  0,  0,
-    0,  9,269,  0,  9,  9,270,  2,  0,  0,  0,  0,  0,  9,271,  2,
-    9,  9,  9,  9,272,  2,  0,  0,129,129,129,129,129,129,129,129,
-  160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,129,
+    0,  0,  1,  2,  0,  3,  0,  3,  0,  0,  4,  5,  0,  6,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,
+    0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  9, 10, 11, 12,
+    0,  0,  0,  0, 10, 13,  0,  0, 14, 10, 10, 15, 16, 17, 18, 19,
+   20, 21, 22, 23, 24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32,
+   33, 34, 22, 35, 36,  0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41,
+   42, 43, 44, 45, 46, 47, 31,  0, 48, 49, 22, 50, 51, 52, 18,  0,
+   53, 49, 22, 54, 51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 18,  0,
+   61, 62, 10, 63, 64, 65, 31, 66, 67, 68, 10, 69, 70, 10, 71, 72,
+   73, 74, 75, 76, 77,  0,  0,  0, 10, 10, 78, 79, 80, 81, 82, 83,
+   84, 85,  0,  0,  0,  0,  0,  0, 10, 86, 10, 87, 10, 88, 89, 90,
+   10, 10, 10, 91, 92, 93,  2,  0, 94,  0, 10, 10, 10, 10, 10, 95,
+   96, 10, 97,  0,  0,  0,  0,  0, 98, 99,100,101, 31, 10,102,103,
+   10, 10,104, 10,105,106,  0,  0, 10,107, 10, 10, 10,108,109,110,
+    2,  2,  0,  0,  0,  0,  0,  0,111, 10, 10,112,113,  2,114,115,
+  116, 10,117, 10, 10, 10,118,119, 10, 10,120,121,122,  0,  0,  0,
+    0,  0,  0,  0,  0,123,124,125,  0,  0,  0,  0,  0,  0,  0,126,
+  127,128,129,  0,  0,  0,130,131,132,  0,  0,  0,  0,  0,  0,133,
+    0,  0,  0,  0,134,  0,  0,  0,  0,  0,  0,  0,  0,  0,135,  0,
+    0,  0,  0, 10, 10, 10,136,137,  0,  0,138,  0,  0,  0,  0,  0,
+  139, 10,140,  0, 10, 10, 10,141,142, 10, 10,143,144,  2,145,146,
+   10, 10,147, 10,148,149,  0,  0,150, 10, 10,151,152,  2,153, 99,
+   10, 10,154,155,156,  2, 10,157, 10, 10, 10,158,159,  0,160,161,
+    0,  0,  0,  0, 10, 10,162,  2,163,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,164,  0,  0,  0,  0,  0,  0,  0,165,
+    0,  0,  0,  0,  0,  0,  0,166,166,167, 34,168,  0,  0,  0,  0,
+  169,170, 10,171, 95,  0,  0,  0,  0,  0,  0,  0, 70, 10,172,  0,
+   10,173,174,  0,  0,  0,  0,  0, 10, 10,175,  2,  0,  0,  0,  0,
+   10, 10,176,173,  0,  0,  0,  0,  0,  0,  0, 10,177,178,  0, 10,
+  179,  0,  0,180,181,  0,  0,  0,182, 10, 10,183,184,185,186,187,
+  188, 10, 10,189,190,  0,  0,  0,191, 10,192,193,194, 10, 10,195,
+  188, 10, 10,196,197,106,198,103, 10, 34,199,200,201,  0,  0,  0,
+  202,203, 95, 10, 10,204,205,  2,206, 21, 22,207,208,209,210,211,
+   10, 10, 10,212,213,214,215,  0,198, 10, 10,216,217,  2,  0,  0,
+   10, 10,218,219,220,221,  0,  0, 10, 10, 10,222,223,  2,  0,  0,
+   10, 10,224,225,  2,  0,  0,  0, 10,226,227,104,228,  0,  0,  0,
+   10, 10,229,230,  0,  0,  0,  0,231,232, 10,233,234,  2,  0,  0,
+    0,  0,235, 10, 10,236,237,  0,238, 10, 10,239,240,241, 10, 10,
+  242,243,  0,  0,  0,  0,  0,  0, 22, 10,218,244,  8, 10, 71, 19,
+   10,245, 74,246,  0,  0,  0,  0,247, 10, 10,248,249,  2,250, 10,
+  251,252,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,253,
+  254, 49, 10,255,256,  2,  0,  0,257,257,257,257,257,257,257,257,
+  257,257,257,258,259,260,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,
+   10, 10, 10,261,  0,  0,  0,  0, 10, 10, 10, 10,262,263,264,264,
+  265,266,  0,  0,  0,  0,267,  0, 10, 10, 10, 10, 10, 10, 10, 10,
+   10, 10, 10, 10, 10,268,  0,  0, 10, 10, 10, 10, 10, 10,106, 71,
+   95,269,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,270,
+   10, 10, 71,271,272,  0,  0,  0,  0, 10,273,  0, 10, 10,274,  2,
+    0,  0,  0,  0,  0, 10,275,  2, 10, 10, 10, 10,276,  2,  0,  0,
+  130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163,
+  163,163,163,163,163,163,163,130,
 };
 
 static inline unsigned
@@ -357,14 +366,14 @@
 static inline uint_fast8_t
 hb_use_get_category (unsigned u)
 {
-  return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
+  return u<921600u?hb_use_u8[2809+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
 }
 
 
 #else
 
 static const uint8_t
-hb_use_u8[3413] =
+hb_use_u8[3483] =
 {
      16,   50,   51,   51,   51,   52,   51,   83,  118,  131,   51,   57,   58,  179,  195,   61,
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
@@ -375,243 +384,248 @@
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
      14,    0,    1,    1,    2,    1,    1,    3,    4,    5,    6,    7,    8,    9,   10,    1,
      11,   12,    1,    1,    1,    1,    1,    1,   13,   14,   15,   16,   17,   18,   19,    1,
-      1,   20,    1,    1,    1,    1,   21,    1,    1,    1,    1,    1,    1,    1,   22,    1,
+      1,   20,    1,    1,    1,    1,   21,    1,   22,    1,    1,    1,    1,    1,   23,   24,
       1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-      1,    1,    1,    1,    1,    1,    1,    1,    1,   23,   24,   25,   26,    1,    1,    1,
-      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   27,
-     28,    1,    1,    1,    1,    1,   29,    1,    1,    1,    1,   30,   31,    1,   32,   33,
-     34,   35,   36,   37,   38,   39,   40,   41,   42,   43,   44,   45,    1,   46,   47,   48,
-     49,   50,   50,   50,   50,   51,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   52,   53,    1,    1,    1,
-     54,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   50,   55,    1,    1,
-      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   56,    1,    1,
-      1,    1,   57,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-      1,    1,   58,   59,    1,   60,    1,    1,    1,    1,   61,    1,    1,    1,    1,    1,
-      1,   62,   63,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,
-     62,    0,    1,    0,    0,    0,    2,    3,    0,    0,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    4,    0,    0,    0,    0,    0,    0,    0,    5,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    8,    0,    0,    0,    0,
-      0,    9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
-     24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,
-     40,   41,   42,   43,   36,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
-      0,   55,   56,   57,   58,   59,    0,    0,    0,   60,   61,   62,   63,   55,   64,   65,
-     66,   67,   55,   55,   68,   69,   70,    0,    0,   71,   72,   73,   74,   55,   75,   76,
-      0,   77,   55,   78,   79,   80,    0,    0,    0,   81,   82,   83,   84,   85,   86,   55,
-     87,   55,   88,   89,    0,    0,    0,   90,   91,    0,    0,    0,    0,    0,    0,    0,
-     92,   93,   94,    0,   95,   96,    0,    0,   97,    0,    0,    0,    0,    0,    0,   98,
-      0,    0,   99,   55,  100,    0,    0,    0,    0,  101,  102,   55,  103,  104,  105,  106,
-    107,   55,  108,  109,    0,  110,  111,  112,  113,   55,  114,  115,  116,   55,  117,  118,
-    119,    0,    0,    0,    0,    0,    0,   55,  120,  121,    0,    0,    0,    0,    0,    0,
-    122,    0,    0,    0,    0,    0,    0,    0,  123,    0,    0,    0,  124,  125,  126,    0,
-      0,  127,  128,  129,    0,    0,    0,   50,  130,    0,    0,    0,    0,  131,  132,    0,
-      0,   55,  133,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   55,  134,    0,
-      0,    0,   99,  135,   99,  136,  137,  138,    0,  139,  140,  141,  142,  143,  144,  145,
-      0,  146,  147,  148,  149,  143,  150,  151,  152,  153,  154,  155,    0,  156,  157,  158,
-    159,  160,  161,  162,  163,    0,    0,    0,    0,   55,  164,  165,  166,  167,  168,  169,
-      0,    0,    0,    0,    0,   55,  170,  171,    0,   55,  172,  173,    0,   55,  174,   66,
-      0,  175,  176,  177,    0,    0,    0,    0,    0,   55,  178,    0,    0,    0,    0,    0,
-      0,  179,  180,  181,    0,    0,  182,  183,  184,  185,  186,  187,   55,  188,    0,    0,
-      0,  189,  190,  191,  192,  193,  194,    0,    0,  195,  196,  197,  198,  199,   66,    0,
-      0,    0,    0,    0,    0,    0,    0,    0,  200,  201,  202,  203,    0,    0,    0,    0,
-      0,   55,   55,   55,   55,   55,   55,   55,   55,   55,  204,  205,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,   66,    0,   55,  206,    0,    0,    0,    0,    0,
-      0,   55,   55,  207,  208,  209,    0,    0,  210,   55,   55,   55,   55,   55,   55,  211,
-      0,   55,   55,   55,  212,  213,    0,    0,    0,    0,    0,    0,  214,    0,    0,    0,
-      0,   55,  215,  216,    0,    0,    0,    0,    0,    0,    0,    0,    0,   99,  217,   55,
-    218,    0,    0,    0,    0,    0,    0,   99,  219,   55,   55,  220,    0,    0,    0,    0,
-      0,  221,  221,  221,  221,  221,  221,  221,  221,  222,  222,  222,  222,  222,  222,  222,
-    223,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
-      0,    2,    2,    2,    2,    2,    0,    0,    0,    3,    0,    0,    0,    0,    0,    4,
-      0,    0,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    0,    0,    0,    0,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,   25,   26,   27,   28,    1,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   29,
+     30,    1,    1,    1,    1,    1,   31,    1,    1,    1,    1,   32,   33,    1,   34,   35,
+     36,   37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,    1,   48,   49,   50,
+     51,   52,   52,   52,   52,   53,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   54,   55,    1,    1,    1,
+     56,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   57,   58,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   59,    1,    1,
+      1,    1,   60,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+      1,    1,   61,   62,    1,   63,    1,    1,    1,    1,   64,    1,    1,    1,    1,    1,
+      1,   65,   66,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
+     65,    0,    1,    2,    2,    0,    3,    4,    0,    0,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    5,    0,    0,    0,    0,    0,    0,    0,    6,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    7,    8,    0,    0,    9,    0,    0,    0,    0,
+      0,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,
+     25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
+     41,   42,   43,   44,   37,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+      0,   56,   57,   58,   59,   60,    0,    0,    0,   61,   62,   63,   64,   56,   65,   66,
+     67,   68,   56,   56,   69,   70,   71,    0,    0,   72,   73,   74,   75,   56,   76,   77,
+      0,   78,   56,   79,   80,   81,    0,    0,    0,   82,   83,   84,   85,   86,   87,   56,
+     88,   56,   89,   90,    0,    0,    0,   91,   92,    0,    0,    0,    0,    0,    0,    0,
+     93,   94,   95,    0,   96,   97,    0,    0,   98,    0,    0,    0,    0,    0,    0,   99,
+      0,    0,    0,    0,    0,    0,    0,    0,  100,    0,  101,   56,  102,    0,    0,    0,
+      0,    0,  103,    0,    0,    0,    0,    0,    0,  104,  105,   56,  106,  107,  108,  109,
+    110,   56,  111,  112,    0,  113,  114,  115,  116,   56,  117,  118,  119,   56,  120,  121,
+    122,    0,    0,    0,    0,    0,    0,   56,  123,  124,    0,    0,    0,    0,    0,    0,
+    125,    0,    0,    0,    0,    0,    0,    0,  126,    0,    0,    0,  127,  128,  129,    0,
+      0,  130,  131,  132,    0,    0,    0,   51,  133,    0,    0,    0,    0,  134,  135,    0,
+      0,   56,  136,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   56,  137,    0,
+      0,    0,  101,  138,  101,  139,  140,  141,    0,  142,  143,  144,  145,  146,  147,  148,
+      0,  149,  150,  151,  152,  146,  153,  154,  155,  156,  157,  158,    0,  159,  160,  161,
+    162,  163,  164,  165,  166,    0,    0,    0,    0,   56,  167,  168,  169,  170,  171,  172,
+      0,    0,    0,    0,    0,   56,  173,  174,    0,   56,  175,  176,    0,   56,  177,   67,
+      0,  178,  179,  180,    0,    0,    0,    0,    0,   56,  181,    0,    0,    0,    0,    0,
+      0,  182,  183,  184,    0,    0,  185,  186,  187,  188,  189,  190,   56,  191,    0,    0,
+      0,  192,  193,  194,  195,  196,  197,    0,    0,  198,  199,  200,  201,  202,   67,    0,
+      0,    0,    0,    0,    0,    0,    0,    0,  203,  204,  205,  206,    0,    0,    0,    0,
+      0,  207,  207,  207,  207,  207,  207,  207,  207,  207,  208,  209,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,   67,    0,   56,  210,    0,    0,    0,    0,    0,
+      0,   56,   56,  211,  212,  213,    0,    0,  214,   56,   56,   56,   56,   56,   56,   56,
+     56,   56,   56,   56,   56,   56,   56,  215,    0,   56,   56,   56,  216,  217,    0,    0,
+      0,    0,    0,    0,  218,    0,    0,    0,    0,   56,  219,  220,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,  101,  221,   56,  222,    0,    0,    0,    0,    0,    0,  101,
+    223,   56,   56,  224,    0,    0,    0,    0,    0,  225,  225,  225,  225,  225,  225,  225,
+    225,  226,  226,  226,  226,  226,  226,  226,  227,    0,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    1,    0,    2,    2,    2,    2,    2,    0,    0,
+      0,    0,    0,    0,    0,    0,    3,    4,    0,    5,    0,    0,    0,    0,    0,    6,
+      0,    0,    7,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    0,    8,    9,    0,    0,    0,    0,    0,    0,
       0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    8,    9,    9,    9,    9,    0,    0,    0,    7,   10,
-      0,    2,    2,    2,    2,   11,   12,    0,    0,    9,   13,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,   14,   15,   16,   17,   18,   19,   20,   14,   21,   22,
-     23,   10,   24,   25,   18,    2,    2,    2,    2,    2,   18,    0,    2,    2,    2,    2,
-      2,    0,    2,    2,    2,    2,    2,    2,    2,   26,   27,   28,    2,    2,    2,    7,
-     28,    7,   28,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    7,    2,    2,
-      2,    7,    7,    0,    2,    2,    0,   15,   16,   17,   18,   29,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    2,   28,    2,    0,    0,    0,    0,    0,    7,
-     34,   10,   13,   28,    2,    2,    7,    0,   28,    7,    2,   28,    7,    2,    0,   35,
-     16,   17,   29,    0,   25,   36,   25,   37,    0,   38,    0,    0,    0,   28,    2,    7,
-      7,    0,    0,    0,    2,    2,    2,    2,    2,   39,   40,   41,    0,    0,    0,    0,
-      0,   10,   13,   28,    2,    2,    2,    2,   28,    2,   28,    2,    2,    2,    2,    2,
-      2,    7,    2,   28,    2,    2,    0,   15,   16,   17,   18,   19,   25,   20,   33,   22,
-      0,    0,    0,    0,    0,   28,   39,   39,   42,   10,   27,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,    0,   15,   43,    0,    0,   25,   20,    0,    0,    2,
-     28,   28,    0,    0,    0,    0,    0,    0,    0,    0,   44,   28,    2,    2,    7,    0,
-      2,    7,    2,    2,    0,   28,    7,    7,    2,    0,   28,    7,    0,    2,    7,    0,
-      2,    2,    2,    2,    2,    2,    0,    0,   21,   14,   45,    0,   46,   31,   46,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    0,   13,   27,   47,    2,    2,    2,    7,
-      2,    7,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,   15,
-     20,   14,   21,   45,   20,   36,   20,   37,    0,    0,    0,   25,   29,    2,    7,    0,
-      0,    8,   27,   28,    2,    2,    2,    7,    2,    2,    2,   28,    2,    2,    0,   15,
-     43,    0,    0,   33,   45,    0,    0,    0,    7,   48,   49,    0,    0,    0,    0,    0,
-      0,    9,   27,    2,    2,    2,    2,    7,    2,    2,    2,    2,    2,    2,   50,   51,
-     21,   21,   17,   29,   46,   31,   46,   32,   52,    0,    0,    0,   33,    0,    0,    0,
-     28,   10,   27,   28,    2,    2,    2,    2,    2,    2,    2,    2,    7,    0,    2,    2,
-      2,    2,   28,    2,    2,    2,    2,   28,    0,    2,    2,    2,    7,    0,   53,    0,
-     33,   21,   20,   29,   29,   16,   46,   46,   23,    0,   21,    0,    0,    0,    0,    0,
-      0,    2,    0,    2,    7,    0,    0,    0,    0,    0,    0,    0,    0,   18,    0,    0,
-      0,    2,    2,   54,   54,   55,    0,    0,   16,    2,    2,    2,    2,   28,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    7,    0,   56,   19,   57,   20,   20,   18,   18,
-     44,   19,    9,   29,    9,    2,    2,   58,   59,   59,   59,   59,   59,   60,   59,   59,
-     59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   61,
-      0,    0,    0,    0,   62,    0,    0,    0,    0,    2,    2,    2,    2,    2,   63,   43,
-     57,   64,   20,   20,   65,   66,   67,   68,   69,    2,    2,    2,    2,    2,    1,    0,
-      3,    2,    2,    2,   21,   18,    2,    2,   70,   69,   71,   72,   63,   71,   27,   27,
-      2,   50,   20,   51,    2,    2,    2,    2,    2,    2,   73,   74,   75,   27,   27,   76,
-     77,    2,    2,    2,    2,    2,   27,   43,    0,    2,   57,   78,    0,    0,    0,    0,
-     28,    2,   57,   45,    0,    0,    0,    0,    0,    2,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,    7,    2,    7,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,   79,   43,   20,   57,   18,   46,   46,   46,   46,   13,   80,   81,   82,
-     83,   84,   85,    0,    0,    0,    0,   86,    0,    7,    0,    0,   28,    0,   87,   79,
-     88,    2,    2,    2,    2,    7,    0,    0,    0,   40,   40,   89,   90,    2,    2,    2,
-      2,    2,    2,    2,    2,   11,    7,    0,    0,   91,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    7,   20,   78,   43,   20,   92,   59,    0,
-      0,   93,   94,   93,   93,   95,   96,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-      0,    2,    2,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    0,
-      0,    2,    2,    2,    2,   27,    0,    0,    0,    2,    2,    2,    2,    2,    7,    0,
-      0,    2,    2,    2,   50,   97,   43,    0,    0,    2,    2,   98,   99,  100,  101,   59,
-     61,  102,   14,   43,   20,   57,   19,   78,   46,   46,   74,    9,    9,    9,  103,   44,
-     38,    9,  104,   72,    2,    2,    2,    2,    2,    2,    2,  105,   20,   18,   18,   20,
-     46,   46,   20,  106,    2,    2,    2,    7,    0,    0,    0,    0,    0,    0,  107,  108,
-    109,  109,  109,    0,    0,    0,    0,    0,    0,  104,   72,    2,    2,    2,    2,    2,
-      2,   58,   59,   57,   23,   20,  110,   59,    2,    2,    2,    2,  105,   20,   21,   43,
-     43,  100,   12,    0,    0,    0,    0,    0,    0,    2,    2,   59,   16,   46,   21,  111,
-    100,  100,  100,  112,  113,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   28,
-      2,    9,   44,  114,  114,  114,    9,  114,  114,   13,  114,  114,  114,   24,    0,   38,
-      0,    0,    0,  115,   49,    9,    3,    0,    0,    0,    0,    0,    0,    0,  116,    0,
-      0,    0,    0,    0,    0,    0,    4,  117,  118,   40,   40,    3,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,  118,  118,  119,  118,  118,  118,  118,  118,  118,  118,
-    118,    0,    0,  120,    0,    0,    0,    0,    0,    0,    5,  120,    0,    0,    0,    0,
-      0,   44,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    7,
-      0,    2,    2,    2,    2,    0,    0,    0,   28,    0,    0,    0,    0,    0,    0,    0,
-    121,    2,   51,    2,  106,    2,    8,    2,    2,    2,   63,   17,   14,    0,    0,   29,
-      0,    2,    2,    0,    0,    0,    0,    0,    0,   27,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,  122,   21,   21,   21,   21,   21,   21,   21,  123,    0,    0,    0,    0,
-      0,    9,    9,    9,    9,    9,    9,    9,    9,    9,    2,    0,    0,    0,    0,    0,
-     50,    2,    2,    2,   20,   20,  124,  114,    0,    2,    2,    2,  125,   18,   57,   18,
-    111,  100,  126,    0,    0,    0,    0,    0,    0,    9,  127,    2,    2,    2,    2,    2,
-      2,    2,  128,   21,   20,   18,   46,  129,  130,  131,    0,    0,    0,    0,    0,    0,
-      0,    2,    2,   50,   28,    2,    2,    2,    2,    2,    2,    2,    2,    8,   20,   57,
-     97,   74,  132,  133,  134,    0,    0,    0,    0,    2,  135,    2,    2,    2,    2,  136,
-      0,   28,    2,   40,    3,    0,   77,   13,    2,   51,   20,  137,   50,   51,    2,    2,
-    103,    8,    7,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  138,   19,
-     23,    0,    0,  139,  140,    0,    0,    0,    0,    2,   63,   43,   21,   78,   45,  141,
-      0,   79,   79,   79,   79,   79,   79,   79,   79,    0,    0,    0,    0,    0,    0,    0,
-      4,  118,  118,  118,  118,  119,    0,    0,    0,    2,    2,    2,    2,    2,    7,    2,
-      2,    2,    7,    2,   28,    2,    2,    2,    2,    2,   28,    2,    2,    2,   28,    7,
-      0,  125,   18,   25,   29,    0,    0,  142,  143,    2,    2,   28,    2,   28,    2,    2,
-      2,    2,    2,    2,    0,   12,   35,    0,  144,    2,    2,   11,   35,    0,   28,    2,
-      2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   28,    2,    2,
-      7,    2,    2,    9,   39,    0,    0,    0,    0,    2,    2,    2,    2,    2,   25,   36,
-      0,    2,    2,    2,  114,  114,  114,  114,  114,  145,    2,    7,    0,    0,    0,    0,
-      0,    2,   12,   12,    0,    0,    0,    0,    0,    7,    2,    2,    7,    2,    2,    2,
-      2,   28,    2,    7,    0,   28,    2,    0,    0,  146,  147,  148,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,   20,   20,   18,   18,   18,   20,   20,  131,    0,    0,    0,
-      0,    0,  149,  149,  149,  149,  149,  149,  149,  149,  149,  149,    2,    2,    2,    2,
-      2,   51,   50,   51,    0,    0,    0,    0,  150,    9,   72,    2,    2,    2,    2,    2,
-      2,   16,   17,   19,   14,   22,   35,    0,    0,    0,   29,    0,    0,    0,    0,    0,
-      0,    9,   47,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   18,   20,  151,
-     20,   19,  152,  153,    2,    2,    2,    2,    2,    0,    0,   63,  154,    0,    0,    0,
-      0,    2,   11,    0,    0,    0,    0,    0,    0,    2,   63,   23,   18,   18,   18,   20,
-     20,  106,  155,    0,    0,   54,  156,   29,  157,   28,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,   21,   17,   20,   20,  158,   42,    0,    0,    0,
-     47,  125,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    7,    7,    2,    2,
-     28,    2,    2,    2,    2,    2,    2,    2,   28,    2,    2,    2,    2,    2,    2,    2,
-      8,   16,   17,   19,   20,  159,   29,    0,    0,    9,    9,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,   56,   15,   21,   14,   21,   45,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    2,    2,   21,    0,    9,    9,    9,   44,
-      0,    9,    9,   44,    0,    0,    0,    0,    0,    2,    2,   63,   23,   18,   18,   18,
-     20,   21,  123,   13,   15,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
-    160,  161,    0,    0,    0,    0,    0,    0,    0,   16,   17,   18,   18,   64,   97,   23,
-    157,    9,  162,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-     63,   23,   18,   18,    0,   46,   46,    9,  163,   35,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    2,    2,   18,    0,   21,   17,   18,   18,   19,   14,   80,
-    163,   36,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    8,  164,
-     23,   18,   20,   20,  162,    7,    0,    0,    0,    2,    2,    2,    2,    2,    7,   41,
-    133,   21,   20,   18,   74,   19,   20,    0,    0,    2,    2,    2,    7,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,   16,   17,   18,   19,   20,  103,  163,   35,    0,
-      0,    2,    2,    2,    7,   28,    0,    2,    2,    2,    2,   28,    7,    2,    2,    2,
-      2,   21,   21,   16,   30,   31,   10,  165,  166,  167,  168,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    0,    2,    2,    2,   63,   23,   18,   18,    0,   20,   21,
-     27,  106,    0,   31,    0,    0,    0,    0,    0,   50,   18,   20,   20,   20,  137,    2,
-      2,    2,  169,  170,    9,   13,  171,   70,  172,    0,    0,    1,  144,    0,    0,    0,
-      0,   50,   18,   20,   14,   17,   18,    2,    2,    2,    2,  155,  155,  155,  173,  173,
-    173,  173,  173,  173,   13,  174,    0,   28,    0,   20,   18,   18,   29,   20,   20,    9,
-    163,    0,   59,   59,   59,   59,   59,   59,   59,   64,   19,   80,   44,    0,    0,    0,
-      0,    2,    2,    2,    7,    2,   28,    2,    2,   50,   20,   20,   29,    0,   36,   20,
-     25,    9,  156,  175,  171,    0,    0,    0,    0,    2,    2,    2,   28,    7,    2,    2,
-      2,    2,    2,    2,    2,    2,   21,   21,   45,   20,   33,   80,   66,    0,    0,    0,
-      0,    2,  176,   64,   45,    0,    0,    0,    0,    9,  177,    2,    2,    2,    2,    2,
-      2,    2,    2,   21,   20,   18,   29,    0,   46,   14,  140,    0,    0,    0,    0,    0,
-      0,  178,  178,  178,  106,  179,  178,    0,    0,  145,    2,    2,  180,  114,  114,  114,
-    114,  114,  114,  114,    0,    0,    0,    0,    0,    9,    9,    9,   44,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    7,    0,   56,  181,   18,   18,   18,   18,   18,   18,
-     18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,    0,    0,    0,
-     38,  114,   24,    0,    0,    0,    0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
-      0,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   56,
-     35,    0,    4,  118,  118,  118,  119,    0,    0,    9,    9,    9,   47,    2,    2,    2,
-      0,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,
-     44,    2,    2,    2,    2,    2,    2,    9,    9,    2,    2,    2,    2,    2,    2,   20,
-     20,    2,    2,   42,   42,   42,   90,    0,    0,    O,    O,    O,   GB,    B,    B,   GB,
-      O,    O,   WJ,FMPst,FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,VMAbv,    O,VMAbv,    B,
-  CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
-   VAbv, VAbv, VAbv, VPst, VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O, VAbv,   GB,VMAbv,VMPst,
-  VMPst,    O,    B, VBlw,    O,    O, VPre, VPre,    O, VPre,    H,    O, VPst,FMAbv,    O,CMBlw,
-      O, VAbv,    O, VAbv,    H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O, MBlw,CMAbv,CMAbv, VPst,
-   VAbv,VMAbv,    O, VPst,    O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,VMPst,    B, VAbv, VAbv,
-      B,    R,    O,  HVM,    O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv, VBlw,    B,  SUB,  SUB,
-    SUB,    O,  SUB,  SUB,    O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst,   IS, VAbv,
-   MPst, MPre, MBlw, MBlw,    B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw, VPst, VPre, VAbv, VAbv,
-  VMPst,VMPst,VMBlw,    B,VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
-  VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,
-      B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,
-    SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,
-  SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
-     CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,    O,    H, MPst, VPst,    H,
-  VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,
-      O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,
-  VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,
-     CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,
-      R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,
-      H,VMPst, VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,    R,
-   MBlw, MBlw,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB, VAbv,    R,VMPst,    H,    H,    B,
-      H,    B,VMBlw,    O, VBlw,
+      2,    2,    2,    2,    2,    2,   10,   11,   11,   11,   11,    0,    0,    0,    9,   12,
+      0,    2,    2,    2,    2,   13,   14,    0,    0,   11,   15,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,   16,   17,   18,   19,   20,   21,   22,   16,   23,   24,
+     25,   12,   26,   27,   20,    2,    2,    2,    2,    2,   20,    0,    2,    2,    2,    2,
+      2,    0,    2,    2,    2,    2,    2,    2,    2,   28,   29,   30,    2,    2,    2,    9,
+     30,    9,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    9,    2,    2,
+      2,    9,    9,    0,    2,    2,    0,   17,   18,   19,   20,   31,   32,   33,   32,   34,
+      0,    0,    0,    0,   35,    0,    0,    2,   30,    2,    0,    0,    0,    0,    0,    9,
+     36,   12,   15,   30,    2,    2,    9,    0,   30,    9,    2,   30,    9,    2,    0,   37,
+     18,   19,   31,    0,   27,   38,   27,   39,    0,   40,    0,    0,    0,   30,    2,    9,
+      9,    0,    0,    0,    2,    2,    2,    2,    2,   41,   42,   43,    0,    0,    0,    0,
+      0,   12,   15,   30,    2,    2,    2,    2,   30,    2,   30,    2,    2,    2,    2,    2,
+      2,    9,    2,   30,    2,    2,    0,   17,   18,   19,   20,   21,   27,   22,   35,   24,
+      0,    0,    0,    0,    0,   30,   41,   41,   44,   12,   29,   30,    2,    2,    2,    9,
+     30,    9,    2,   30,    2,    2,    0,   17,   45,    0,    0,   27,   22,    0,    0,    2,
+     30,   30,    0,    0,    0,    0,    0,    0,    0,    0,   46,   30,    2,    2,    9,    0,
+      2,    9,    2,    2,    0,   30,    9,    9,    2,    0,   30,    9,    0,    2,    9,    0,
+      2,    2,    2,    2,    2,    2,    0,    0,   23,   16,   47,    0,   48,   33,   48,   34,
+      0,    0,    0,    0,   35,    0,    0,    0,    0,   15,   29,   49,    2,    2,    2,    9,
+      2,    9,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,   17,
+     22,   16,   23,   47,   22,   38,   22,   39,    0,    0,    0,   27,   31,    2,    9,    0,
+      0,   10,   29,   30,    2,    2,    2,    9,    2,    2,    2,   30,    2,    2,    0,   17,
+     45,    0,    0,   35,   47,    0,    0,    0,    9,   50,   51,    0,    0,    0,    0,    0,
+      0,   11,   29,    2,    2,    2,    2,    9,    2,    2,    2,    2,    2,    2,   52,   53,
+     23,   23,   19,   31,   48,   33,   48,   34,   54,    0,    0,    0,   35,    0,    0,    0,
+     30,   12,   29,   30,    2,    2,    2,    2,    2,    2,    2,    2,    9,    0,    2,    2,
+      2,    2,   30,    2,    2,    2,    2,   30,    0,    2,    2,    2,    9,    0,   55,    0,
+     35,   23,   22,   31,   31,   18,   48,   48,   25,    0,   23,    0,    0,    0,    0,    0,
+      0,    2,    0,    2,    9,    0,    0,    0,    0,    0,    0,    0,    0,   20,    0,    0,
+      0,    2,    2,   56,   56,   57,    0,    0,   18,    2,    2,    2,    2,   30,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    9,    0,   58,   21,   59,   22,   22,   20,   20,
+     46,   21,   11,   31,   11,    2,    2,   60,   61,   61,   61,   61,   61,   62,   61,   61,
+     61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   63,
+      0,    0,    0,    0,   64,    0,    0,    0,    0,    2,    2,    2,    2,    2,   65,   45,
+     59,   66,   22,   22,   67,   68,   69,   70,   71,    2,    2,    2,    2,    2,    1,    0,
+      5,    2,    2,    2,   23,   20,    2,    2,   72,   71,   73,   74,   65,   73,   29,   29,
+      2,   52,   22,   53,    2,    2,    2,    2,    2,    2,   75,   76,   77,   29,   29,   78,
+     79,    2,    2,    2,    2,    2,   29,   45,    0,    2,   59,   80,    0,    0,    0,    0,
+     30,    2,   59,   47,    0,    0,    0,    0,    0,    2,   59,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,    9,    2,    9,   59,    0,    0,    0,    0,    0,
+      0,    2,    2,   81,   45,   22,   59,   20,   48,   48,   48,   48,   15,   82,   83,   84,
+     85,   86,   87,    0,    0,    0,    0,   88,    0,    9,    0,    0,   30,    0,   89,   81,
+     90,    2,    2,    2,    2,    9,    0,    0,    0,   42,   42,   91,   92,    2,    2,    2,
+      2,    2,    2,    2,    2,   13,    9,    0,    0,   93,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    9,   22,   80,   45,   22,   94,   61,    0,
+      0,   95,   96,   95,   95,   97,   98,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+      0,    2,    2,    9,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    0,
+      0,    2,    2,    2,    2,   29,    0,    0,    0,    2,    2,    2,    2,    2,    9,    0,
+      0,    2,    2,    2,   52,   99,   45,    0,    0,    2,    2,  100,  101,  102,  103,   61,
+     63,  104,   16,   45,   22,   59,   21,   80,   48,   48,   76,   11,   11,   11,  105,   46,
+     40,   11,  106,   74,    2,    2,    2,    2,    2,    2,    2,  107,   22,   20,   20,   22,
+     48,   48,   22,  108,    2,    2,    2,    9,    0,    0,    0,    0,    0,    0,  109,  110,
+    111,  111,  111,    0,    0,    0,    0,    0,    0,  106,   74,    2,    2,    2,    2,    2,
+      2,   60,   61,   59,   25,   22,  112,   61,    2,    2,    2,    2,  107,   22,   23,   45,
+     45,  102,   14,    0,    0,    0,    0,    0,    0,    2,    2,   61,   18,   48,   23,  113,
+    102,  102,  102,  114,  115,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   30,
+      2,   11,   46,  116,  116,  116,   11,  116,  116,   15,  116,  116,  116,   26,    0,   40,
+      0,    0,    0,  117,   51,   11,    5,    0,    0,    0,    0,    0,    0,    0,  118,    0,
+      0,    0,    0,    0,    0,    0,    6,  119,  120,   42,   42,    5,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,  120,  120,  121,  120,  120,  120,  120,  120,  120,  120,
+    120,    0,    0,  122,    0,    0,    0,    0,    0,    0,    7,  122,    0,    0,    0,    0,
+      0,   46,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    9,
+      0,    0,    0,    0,  123,  123,    0,    0,    0,    2,    2,    2,    2,    0,    0,    0,
+     30,    0,    0,    0,    0,    0,    0,    0,  124,    0,  123,  123,    0,    0,    0,    0,
+      0,    2,   53,    2,  108,    2,   10,    2,    2,    2,   65,   19,   16,    0,    0,   31,
+      0,    2,    2,    0,    0,    0,    0,    0,    0,   29,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,  125,   23,   23,   23,   23,   23,   23,   23,  126,    0,    0,    0,    0,
+      0,   11,   11,   11,   11,   11,   11,   11,   11,   11,    2,    0,    0,    0,    0,    0,
+     52,    2,    2,    2,   22,   22,  127,  116,    0,    2,    2,    2,  128,   20,   59,   20,
+    113,  102,  129,    0,    0,    0,    0,    0,    0,   11,  130,    2,    2,    2,    2,    2,
+      2,    2,  131,   23,   22,   20,   48,  132,  133,  134,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,   52,   30,    2,    2,    2,    2,    2,    2,    2,    2,   10,   22,   59,
+     99,   76,  135,  136,  137,    0,    0,    0,    0,    2,  138,    2,    2,    2,    2,  139,
+      0,   30,    2,   42,    5,    0,   79,   15,    2,   53,   22,  140,   52,   53,    2,    2,
+    105,   10,    9,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  141,   21,
+     25,    0,    0,  142,  143,    0,    0,    0,    0,    2,   65,   45,   23,   80,   47,  144,
+      0,   81,   81,   81,   81,   81,   81,   81,   81,    0,    0,    0,    0,    0,    0,    0,
+      6,  120,  120,  120,  120,  121,    0,    0,    0,    2,    2,    2,    2,    2,    9,    2,
+      2,    2,    9,    2,   30,    2,    2,    2,    2,    2,   30,    2,    2,    2,   30,    9,
+      0,  128,   20,   27,   31,    0,    0,  145,  146,    2,    2,   30,    2,   30,    2,    2,
+      2,    2,    2,    2,    0,   14,   37,    0,  147,    2,    2,   13,   37,    0,   30,    2,
+      2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   30,    2,    2,
+      9,    2,    2,   11,   41,    0,    0,    0,    0,    2,    2,    2,    2,    2,   27,   38,
+      0,    2,    2,    2,  116,  116,  116,  116,  116,  148,    2,    9,    0,    0,    0,    0,
+      0,    2,   14,   14,    0,    0,    0,    0,    0,    9,    2,    2,    9,    2,    2,    2,
+      2,   30,    2,    9,    0,   30,    2,    0,    0,  149,  150,  151,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,   22,   22,   20,   20,   20,   22,   22,  134,    0,    0,    0,
+      0,    0,  152,  152,  152,  152,  152,  152,  152,  152,  152,  152,    2,    2,    2,    2,
+      2,   53,   52,   53,    0,    0,    0,    0,  153,   11,   74,    2,    2,    2,    2,    2,
+      2,   18,   19,   21,   16,   24,   37,    0,    0,    0,   31,    0,    0,    0,    0,    0,
+      0,   11,   49,    2,    2,    2,    2,    2,    2,    2,    2,    2,  128,   20,   22,  154,
+     22,   21,  155,  156,    2,    2,    2,    2,    2,    0,    0,   65,  157,    0,    0,    0,
+      0,    2,   13,    0,    0,    0,    0,    0,    0,    2,   65,   25,   20,   20,   20,   22,
+     22,  108,  158,    0,    0,   56,  159,   31,  160,   30,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,   23,   19,   22,   22,  161,   44,    0,    0,    0,
+     49,  128,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    9,    9,    2,    2,
+     30,    2,    2,    2,    2,    2,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,
+     10,   18,   19,   21,   22,  162,   31,    0,    0,   11,   11,   30,    2,    2,    2,    9,
+     30,    9,    2,   30,    2,    2,   58,   17,   23,   16,   23,   47,   32,   33,   32,   34,
+      0,    0,    0,    0,   35,    0,    0,    0,    2,    2,   23,    0,   11,   11,   11,   46,
+      0,   11,   11,   46,    0,    0,    0,    0,    0,    2,    2,   65,   25,   20,   20,   20,
+     22,   23,  126,   15,   17,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
+    163,  164,    0,    0,    0,    0,    0,    0,    0,   18,   19,   20,   20,   66,   99,   25,
+    160,   11,  165,    9,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+     65,   25,   20,   20,    0,   48,   48,   11,  166,   37,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    2,    2,   20,    0,   23,   19,   20,   20,   21,   16,   82,
+    166,   38,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,   10,  167,
+     25,   20,   22,   22,  165,    9,    0,    0,    0,    2,    2,    2,    2,    2,    9,   43,
+    136,   23,   22,   20,   76,   21,   22,    0,    0,    2,    2,    2,    9,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,   18,   19,   20,   21,   22,  105,  166,   37,    0,
+      0,    2,    2,    2,    9,   30,    0,    2,    2,    2,    2,   30,    9,    2,    2,    2,
+      2,   23,   23,   18,   32,   33,   12,  168,  169,  170,  171,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    0,    2,    2,    2,   65,   25,   20,   20,    0,   22,   23,
+     29,  108,    0,   33,    0,    0,    0,    0,    0,   52,   20,   22,   22,   22,  140,    2,
+      2,    2,  172,  173,   11,   15,  174,   72,  175,    0,    0,    1,  147,    0,    0,    0,
+      0,   52,   20,   22,   16,   19,   20,    2,    2,    2,    2,  158,  158,  158,  176,  176,
+    176,  176,  176,  176,   15,  177,    0,   30,    0,   22,   20,   20,   31,   22,   22,   11,
+    166,    0,   61,   61,   61,   61,   61,   61,   61,   66,   21,   82,   46,    0,    0,    0,
+      0,    2,    2,    2,    9,    2,   30,    2,    2,   52,   22,   22,   31,    0,   38,   22,
+     27,   11,  159,  178,  174,    0,    0,    0,    0,    2,    2,    2,   30,    9,    2,    2,
+      2,    2,    2,    2,    2,    2,   23,   23,   47,   22,   35,   82,   68,    0,    0,    0,
+      0,    2,  179,   66,   47,    0,    0,    0,    0,   11,  180,    2,    2,    2,    2,    2,
+      2,    2,    2,   23,   22,   20,   31,    0,   48,   16,  143,    0,    0,    0,    0,    0,
+      0,  181,  181,  181,  181,  181,  181,  181,  181,  182,  182,  182,  183,  184,  182,  181,
+    181,  185,  181,  181,  186,  187,  187,  187,  187,  187,  187,  187,    0,    0,    0,    0,
+      0,   11,   11,   11,   46,    0,    0,    0,    0,    2,    2,    2,    2,    2,    9,    0,
+     58,  188,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+     20,   20,   20,   20,   20,    0,    0,    0,   40,  116,   26,    0,    0,    0,    0,    0,
+      0,    0,    0,    9,    0,    0,    0,    0,    0,    2,    2,    2,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,   58,   37,    0,    6,  120,  120,  120,  121,    0,
+      0,   11,   11,   11,   49,    2,    2,    2,    0,    2,    2,    2,    2,    2,    0,    0,
+      2,    2,    2,    2,    2,    2,    2,    2,   46,    2,    2,    2,    2,    2,    2,   11,
+     11,    2,    2,    2,    2,    2,    2,   22,   22,    2,    2,   44,   44,   44,   92,    0,
+      0,    O,    O,    O,   GB,    B,    B,    O,   SB,    O,   SE,   GB,    O,    O,   WJ,FMPst,
+  FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,VMAbv,    O,VMAbv,    B,CMBlw,CMBlw,CMBlw,VMAbv,
+  VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst,
+   VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O, VAbv,   GB,VMAbv,VMPst,VMPst,    O,    B, VBlw,
+      O,    O, VPre, VPre,    O, VPre,    H,    O, VPst,FMAbv,    O,CMBlw,    O, VAbv,    O, VAbv,
+      H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv,    O, VPst,
+      O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,VMPst,    B, VAbv, VAbv,    B,    R,    O,  HVM,
+      O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv, VBlw,    B,  SUB,  SUB,  SUB,    O,  SUB,  SUB,
+      O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst,   IS, VAbv, MPst, MPre, MBlw, MBlw,
+      B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw,    B,
+  VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv,   IS,
+  FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,    B, VAbv,  SUB, FPst,
+   FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,  SUB, FAbv, FAbv, MAbv,
+    SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,SMAbv,SMBlw,SMAbv,SMAbv,
+  SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,
+    CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,   SB,   SE,    O,    H, MPst, VPst,    H,VMAbv, VAbv,
+  VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,    O, VBlw,
+   MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,VMPst,   IS,
+      O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,   CS,   CS,
+      B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,    R,CMBlw,
+   VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,    H,VMPst,
+   VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,    R, MBlw, MBlw,
+     GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB, VAbv,    R,VMPst,    G,    G,    J,    J,    J,
+     SB,   SE,    J,   HR,    G,    G,   HM,   HM,   HM,    O, VBlw,
 };
 static const uint16_t
-hb_use_u16[448] =
+hb_use_u16[456] =
 {
-    0,  0,  1,  2,  3,  4,  0,  5,  6,  0,  7,  0,  8,  9, 10, 11,
-    9, 12, 13,  9,  9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
-   17, 25, 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35,  0,
-   17, 36, 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46,
-   30,  0, 47, 48, 21, 49, 50, 51, 17,  0, 52, 48, 21, 53, 50, 54,
-   17, 55, 56, 48,  9, 57, 58, 59, 60, 61,  9, 62, 63, 64, 30, 65,
-   66, 67,  9, 68, 69,  9, 70, 71, 72, 73, 74, 75, 76,  0,  9,  9,
-   77, 78, 79, 80, 81, 82, 83, 84,  9, 85,  9, 86,  9, 87, 88, 89,
-    9, 90, 91, 92,  2,  0, 93,  0,  9, 94, 95,  9, 96,  0, 97, 98,
-   99,100, 30,  9,101,102,103,  9,104,105,  9,106,  9,107,108,109,
-    2,  2,110,  9,  9,111,112,  2,113,114,115,  9,116,  9,117,118,
-  119,120,121,  0,  0,122,123,124,  0,125,126,127,128,  0,129,130,
-  131,  0,  0,132,133,  0,  0,  9,134,135,136,  9,137,  0,  9,138,
-  139,  9,  9,140,141,  2,142,143,144,  9,145,146,147,  9,  9,148,
-  149,  2,150, 98,151,152,153,  2,  9,154,  9,155,156,  0,157,158,
-  159,  2,160,  0,  0,161,  0,162,  0,163,163,164, 33,165,166,167,
-    9,168, 94,  0,169,  0,  9,170,171,  0,172,  2,173,170,174,175,
-  176,  0,  0,177,178,  0,179,  9,  9,180,181,182,183,184,185,  9,
-    9,186,187,  0,188,  9,189,190,191,  9,  9,192,  9,193,194,105,
-  195,102,  9, 33,196,197,198,  0,199,200, 94,  9,  9,201,202,  2,
-  203, 20, 21,204,205,206,207,208,  9,209,210,211,212,  0,195,  9,
-    9,213,214,  2,215,216,217,218,  9,219,220,  2,221,222,  9,223,
-  224,103,225,  0,226,227,228,229,  9,230,231,  2,232,  9,  9,233,
-  234,  0,235,  9,  9,236,237,238,239,240, 21,  9,215,241,  7,  9,
-   70, 18,  9,242, 73,243,244,  9,  9,245,246,  2,247,  9,248,249,
-    9,250,251, 48,  9,252,253,  2,  9,254,255,256,  9,257,258,259,
-  260,260,261,262,263,  0,  9,264,105, 70, 94,265,  0,266, 70,267,
-  268,  0,269,  0,270,  2,271,  2,272,  2,129,129,160,160,160,129,
+    0,  0,  1,  2,  0,  3,  4,  5,  0,  6,  7,  0,  8,  0,  9, 10,
+   11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32, 33, 34, 22, 35,
+   36,  0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41, 42, 43, 44, 45,
+   46, 47, 31,  0, 48, 49, 22, 50, 51, 52, 18,  0, 53, 49, 22, 54,
+   51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 61, 62, 10, 63, 64, 65,
+   31, 66, 67, 68, 10, 69, 70, 10, 71, 72, 73, 74, 75, 76, 77,  0,
+   10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 10, 86, 10, 87, 10, 88,
+   89, 90, 10, 91, 92, 93,  2,  0, 94,  0, 10, 95, 96, 10, 97,  0,
+   98, 99,100,101, 31, 10,102,103,104, 10,105,106, 10,107, 10,108,
+  109,110,  2,  2,111, 10, 10,112,113,  2,114,115,116, 10,117, 10,
+  118,119,120,121,122,  0,  0,123,124,125,  0,126,127,128,129,  0,
+  130,131,132,  0,  0,133,134,  0,135,  0,  0, 10,136,137,138,  0,
+  139, 10,140,  0, 10,141,142, 10, 10,143,144,  2,145,146,147, 10,
+  148,149,150, 10, 10,151,152,  2,153, 99,154,155,156,  2, 10,157,
+   10,158,159,  0,160,161,162,  2,163,  0,  0,164,  0,165,  0,166,
+  166,167, 34,168,169,170, 10,171, 95,  0,172,  0, 10,173,174,  0,
+  175,  2,176,173,177,178,179,  0,  0,180,181,  0,182, 10, 10,183,
+  184,185,186,187,188, 10, 10,189,190,  0,191, 10,192,193,194, 10,
+   10,195, 10,196,197,106,198,103, 10, 34,199,200,201,  0,202,203,
+   95, 10, 10,204,205,  2,206, 21, 22,207,208,209,210,211, 10,212,
+  213,214,215,  0,198, 10, 10,216,217,  2,218,219,220,221, 10,222,
+  223,  2,224,225, 10,226,227,104,228,  0,229,230,231,232, 10,233,
+  234,  2,235, 10, 10,236,237,  0,238, 10, 10,239,240,241,242,243,
+   22, 10,218,244,  8, 10, 71, 19, 10,245, 74,246,247, 10, 10,248,
+  249,  2,250, 10,251,252, 10,253,254, 49, 10,255,256,  2,257,257,
+  257,258,259,260, 10,261,262,263,264,264,265,266,267,  0, 10,268,
+  106, 71, 95,269,  0,270, 71,271,272,  0,273,  0,274,  2,275,  2,
+  276,  2,130,130,163,163,163,130,
 };
 
 static inline unsigned
@@ -622,7 +636,7 @@
 static inline uint_fast8_t
 hb_use_get_category (unsigned u)
 {
-  return u<921600u?hb_use_u8[3049+(((hb_use_u8[865+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
+  return u<921600u?hb_use_u8[3105+(((hb_use_u8[889+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
 }
 
 #endif
@@ -633,7 +647,9 @@
 #undef G
 #undef GB
 #undef H
+#undef HM
 #undef HN
+#undef HR
 #undef HVM
 #undef IS
 #undef J
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc	2024-01-16 16:19:00.000000000 +0000
@@ -377,6 +377,9 @@
 #define POST_BASE_FLAGS64 (FLAG64 (USE(FAbv)) | \
                            FLAG64 (USE(FBlw)) | \
                            FLAG64 (USE(FPst)) | \
+                           FLAG64 (USE(FMAbv)) | \
+                           FLAG64 (USE(FMBlw)) | \
+                           FLAG64 (USE(FMPst)) | \
                            FLAG64 (USE(MAbv)) | \
                            FLAG64 (USE(MBlw)) | \
                            FLAG64 (USE(MPst)) | \
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc	2024-01-16 16:19:00.000000000 +0000
@@ -10,8 +10,8 @@
  * # Date: 2015-03-12, 21:17:00 GMT [AG]
  * # Date: 2019-11-08, 23:22:00 GMT [AG]
  *
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
+ * # Scripts-15.1.0.txt
+ * # Date: 2023-07-28, 16:01:07 GMT
  */
 
 #include "hb.hh"
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -57,6 +57,16 @@
   // Reserved = 0xFFFC                          /* Reserved for future use — set to zero. */
 };
 
+static bool axis_value_is_outside_axis_range (hb_tag_t axis_tag, float axis_value,
+                                              const hb_hashmap_t *user_axes_location)
+{
+  if (!user_axes_location->has (axis_tag))
+    return false;
+
+  Triple axis_range = user_axes_location->get (axis_tag);
+  return (axis_value < axis_range.minimum || axis_value > axis_range.maximum);
+}
+
 struct StatAxisRecord
 {
   int cmp (hb_tag_t key) const { return tag.cmp (key); }
@@ -96,23 +106,19 @@
   }
 
   bool keep_axis_value (const hb_array_t axis_records,
-                        const hb_hashmap_t *user_axes_location) const
+                        const hb_hashmap_t *user_axes_location) const
   {
     hb_tag_t axis_tag = get_axis_tag (axis_records);
     float axis_value = get_value ();
 
-    if (!user_axes_location->has (axis_tag) ||
-        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
-      return true;
-
-    return false;
+    return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
   }
 
   bool subset (hb_subset_context_t *c,
                const hb_array_t axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t* user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t* user_axes_location = &c->plan->user_axes_location;
 
     if (keep_axis_value (axis_records, user_axes_location))
       return_trace (c->serializer->embed (this));
@@ -155,23 +161,19 @@
   }
 
   bool keep_axis_value (const hb_array_t axis_records,
-                        const hb_hashmap_t *user_axes_location) const
+                        const hb_hashmap_t *user_axes_location) const
   {
     hb_tag_t axis_tag = get_axis_tag (axis_records);
     float axis_value = get_value ();
 
-    if (!user_axes_location->has (axis_tag) ||
-        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
-      return true;
-
-    return false;
+    return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
   }
 
   bool subset (hb_subset_context_t *c,
                const hb_array_t axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t* user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t* user_axes_location = &c->plan->user_axes_location;
 
     if (keep_axis_value (axis_records, user_axes_location))
       return_trace (c->serializer->embed (this));
@@ -218,23 +220,19 @@
   }
 
   bool keep_axis_value (const hb_array_t axis_records,
-                        const hb_hashmap_t *user_axes_location) const
+                        const hb_hashmap_t *user_axes_location) const
   {
     hb_tag_t axis_tag = get_axis_tag (axis_records);
     float axis_value = get_value ();
 
-    if (!user_axes_location->has (axis_tag) ||
-        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
-      return true;
-
-    return false;
+    return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
   }
 
   bool subset (hb_subset_context_t *c,
                const hb_array_t axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t* user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t* user_axes_location = &c->plan->user_axes_location;
 
     if (keep_axis_value (axis_records, user_axes_location))
       return_trace (c->serializer->embed (this));
@@ -291,7 +289,7 @@
   { return axisValues.as_array (axisCount)[axis_index]; }
 
   bool keep_axis_value (const hb_array_t axis_records,
-                        const hb_hashmap_t *user_axes_location) const
+                        const hb_hashmap_t *user_axes_location) const
   {
     hb_array_t axis_value_records = axisValues.as_array (axisCount);
 
@@ -301,8 +299,7 @@
       float axis_value = rec.get_value ();
       hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag ();
 
-      if (user_axes_location->has (axis_tag) &&
-          fabsf(axis_value - user_axes_location->get (axis_tag)) > 0.001f)
+      if (axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location))
         return false;
     }
 
@@ -313,7 +310,7 @@
                const hb_array_t axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t *user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t *user_axes_location = &c->plan->user_axes_location;
     if (!keep_axis_value (axis_records, user_axes_location))
       return_trace (false);
 
@@ -402,7 +399,7 @@
   }
 
   bool keep_axis_value (const hb_array_t axis_records,
-                        hb_hashmap_t *user_axes_location) const
+                        hb_hashmap_t *user_axes_location) const
   {
     switch (u.format)
     {
@@ -451,8 +448,6 @@
                const hb_array_t axis_records) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
 
     auto axisValueOffsets = as_array (axisValueCount);
     count = 0;
@@ -517,7 +512,7 @@
     return axis_value.get_value_name_id ();
   }
 
-  void collect_name_ids (hb_hashmap_t *user_axes_location,
+  void collect_name_ids (hb_hashmap_t *user_axes_location,
                          hb_set_t *nameids_to_retain /* OUT */) const
   {
     if (!has_data ()) return;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -6,8 +6,8 @@
  *
  * on files with these headers:
  *
- * 
- * File-Date: 2022-03-02
+ * 
+ * File-Date: 2023-08-02
  */
 
 #ifndef HB_OT_TAG_TABLE_HH
@@ -257,7 +257,7 @@
   {HB_TAG('a','i','i',' '),     HB_TAG('S','Y','R',' ')},       /* Assyrian Neo-Aramaic -> Syriac */
 /*{HB_TAG('a','i','o',' '),     HB_TAG('A','I','O',' ')},*/     /* Aiton */
   {HB_TAG('a','i','w',' '),     HB_TAG('A','R','I',' ')},       /* Aari */
-  {HB_TAG('a','j','p',' '),     HB_TAG('A','R','A',' ')},       /* South Levantine Arabic -> Arabic */
+  {HB_TAG('a','j','p',' '),     HB_TAG('A','R','A',' ')},       /* South Levantine Arabic (retired code) -> Arabic */
   {HB_TAG('a','j','t',' '),     HB_TAG('A','R','A',' ')},       /* Judeo-Tunisian Arabic (retired code) -> Arabic */
   {HB_TAG('a','k','b',' '),     HB_TAG('A','K','B',' ')},       /* Batak Angkola */
   {HB_TAG('a','k','b',' '),     HB_TAG('B','T','K',' ')},       /* Batak Angkola -> Batak */
@@ -269,7 +269,7 @@
 /*{HB_TAG('a','n','g',' '),     HB_TAG('A','N','G',' ')},*/     /* Old English (ca. 450-1100) -> Anglo-Saxon */
   {HB_TAG('a','o','a',' '),     HB_TAG('C','P','P',' ')},       /* Angolar -> Creoles */
   {HB_TAG('a','p','a',' '),     HB_TAG('A','T','H',' ')},       /* Apache [collection] -> Athapaskan */
-  {HB_TAG('a','p','c',' '),     HB_TAG('A','R','A',' ')},       /* North Levantine Arabic -> Arabic */
+  {HB_TAG('a','p','c',' '),     HB_TAG('A','R','A',' ')},       /* Levantine Arabic -> Arabic */
   {HB_TAG('a','p','d',' '),     HB_TAG('A','R','A',' ')},       /* Sudanese Arabic -> Arabic */
   {HB_TAG('a','p','j',' '),     HB_TAG('A','T','H',' ')},       /* Jicarilla Apache -> Athapaskan */
   {HB_TAG('a','p','k',' '),     HB_TAG('A','T','H',' ')},       /* Kiowa Apache -> Athapaskan */
@@ -1211,6 +1211,7 @@
   {HB_TAG('p','p','a',' '),     HB_TAG('B','A','G',' ')},       /* Pao (retired code) -> Baghelkhandi */
   {HB_TAG('p','r','e',' '),     HB_TAG('C','P','P',' ')},       /* Principense -> Creoles */
 /*{HB_TAG('p','r','o',' '),     HB_TAG('P','R','O',' ')},*/     /* Old Provençal (to 1500) -> Provençal / Old Provençal */
+  {HB_TAG('p','r','p',' '),     HB_TAG('G','U','J',' ')},       /* Parsi (retired code) -> Gujarati */
   {HB_TAG('p','r','s',' '),     HB_TAG('D','R','I',' ')},       /* Dari */
   {HB_TAG('p','r','s',' '),     HB_TAG('F','A','R',' ')},       /* Dari -> Persian */
   {HB_TAG('p','s','e',' '),     HB_TAG('M','L','Y',' ')},       /* Central Malay -> Malay */
@@ -1439,7 +1440,7 @@
   {HB_TAG('t','c','h',' '),     HB_TAG('C','P','P',' ')},       /* Turks And Caicos Creole English -> Creoles */
   {HB_TAG('t','c','p',' '),     HB_TAG('Q','I','N',' ')},       /* Tawr Chin -> Chin */
   {HB_TAG('t','c','s',' '),     HB_TAG('C','P','P',' ')},       /* Torres Strait Creole -> Creoles */
-  {HB_TAG('t','c','y',' '),     HB_TAG('T','U','L',' ')},       /* Tulu -> Tumbuka */
+  {HB_TAG('t','c','y',' '),     HB_TAG('T','U','L',' ')},       /* Tulu */
   {HB_TAG('t','c','z',' '),     HB_TAG('Q','I','N',' ')},       /* Thado Chin -> Chin */
 /*{HB_TAG('t','d','d',' '),     HB_TAG('T','D','D',' ')},*/     /* Tai Nüa -> Dehong Dai */
   {HB_TAG('t','d','x',' '),     HB_TAG('M','L','G',' ')},       /* Tandroy-Mahafaly Malagasy -> Malagasy */
@@ -1495,8 +1496,8 @@
   {HB_TAG('t','t','q',' '),     HB_TAG('T','M','H',' ')},       /* Tawallammat Tamajaq -> Tamashek */
   {HB_TAG('t','t','q',' '),     HB_TAG('B','B','R',' ')},       /* Tawallammat Tamajaq -> Berber */
   {HB_TAG('t','u','a',' '),     HB_TAG_NONE            },       /* Wiarumus != Turoyo Aramaic */
-  {HB_TAG('t','u','l',' '),     HB_TAG_NONE            },       /* Tula != Tumbuka */
-/*{HB_TAG('t','u','m',' '),     HB_TAG('T','U','M',' ')},*/     /* Tumbuka -> Tulu */
+  {HB_TAG('t','u','l',' '),     HB_TAG_NONE            },       /* Tula != Tulu */
+/*{HB_TAG('t','u','m',' '),     HB_TAG('T','U','M',' ')},*/     /* Tumbuka */
   {HB_TAG('t','u','u',' '),     HB_TAG('A','T','H',' ')},       /* Tututni -> Athapaskan */
   {HB_TAG('t','u','v',' '),     HB_TAG_NONE            },       /* Turkana != Tuvin */
   {HB_TAG('t','u','y',' '),     HB_TAG('K','A','L',' ')},       /* Tugen -> Kalenjin */
@@ -1581,6 +1582,7 @@
   {HB_TAG('y','b','a',' '),     HB_TAG_NONE            },       /* Yala != Yoruba */
   {HB_TAG('y','b','b',' '),     HB_TAG('B','M','L',' ')},       /* Yemba -> Bamileke */
   {HB_TAG('y','b','d',' '),     HB_TAG('A','R','K',' ')},       /* Yangbye (retired code) -> Rakhine */
+  {HB_TAG('y','c','r',' '),     HB_TAG_NONE            },       /* Yilan Creole != Y-Cree */
   {HB_TAG('y','d','d',' '),     HB_TAG('J','I','I',' ')},       /* Eastern Yiddish -> Yiddish */
 /*{HB_TAG('y','g','p',' '),     HB_TAG('Y','G','P',' ')},*/     /* Gepo */
   {HB_TAG('y','i','h',' '),     HB_TAG('J','I','I',' ')},       /* Western Yiddish -> Yiddish */
@@ -1602,6 +1604,7 @@
   {HB_TAG('z','g','n',' '),     HB_TAG('Z','H','A',' ')},       /* Guibian Zhuang -> Zhuang */
   {HB_TAG('z','h','d',' '),     HB_TAG('Z','H','A',' ')},       /* Dai Zhuang -> Zhuang */
   {HB_TAG('z','h','n',' '),     HB_TAG('Z','H','A',' ')},       /* Nong Zhuang -> Zhuang */
+  {HB_TAG('z','k','b',' '),     HB_TAG('K','H','A',' ')},       /* Koibal (retired code) -> Khakass */
   {HB_TAG('z','l','j',' '),     HB_TAG('Z','H','A',' ')},       /* Liujiang Zhuang -> Zhuang */
   {HB_TAG('z','l','m',' '),     HB_TAG('M','L','Y',' ')},       /* Malay */
   {HB_TAG('z','l','n',' '),     HB_TAG('Z','H','A',' ')},       /* Lianshan Zhuang -> Zhuang */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc	2024-01-16 16:19:00.000000000 +0000
@@ -412,7 +412,7 @@
 /**
  * hb_ot_tags_from_script_and_language:
  * @script: an #hb_script_t to convert.
- * @language: an #hb_language_t to convert.
+ * @language: (nullable): an #hb_language_t to convert.
  * @script_count: (inout) (optional): maximum number of script tags to retrieve (IN)
  * and actual number of script tags retrieved (OUT)
  * @script_tags: (out) (optional): array of size at least @script_count to store the
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -72,6 +72,65 @@
     return_trace (c->check_struct (this));
   }
 
+  void set_mapping (float from_coord, float to_coord)
+  {
+    coords[0].set_float (from_coord);
+    coords[1].set_float (to_coord);
+  }
+
+  bool is_outside_axis_range (const Triple& axis_range) const
+  {
+    float from_coord = coords[0].to_float ();
+    return !axis_range.contains (from_coord);
+  }
+
+  bool must_include () const
+  {
+    float from_coord = coords[0].to_float ();
+    float to_coord = coords[1].to_float ();
+    return (from_coord == -1.f && to_coord == -1.f) ||
+           (from_coord == 0.f && to_coord == 0.f) ||
+           (from_coord == 1.f && to_coord == 1.f);
+  }
+
+  void instantiate (const Triple& axis_range,
+                    const Triple& unmapped_range,
+                    const TripleDistances& triple_distances)
+  {
+    float from_coord = coords[0].to_float ();
+    float to_coord = coords[1].to_float ();
+
+    from_coord = renormalizeValue (from_coord, unmapped_range, triple_distances);
+    to_coord = renormalizeValue (to_coord, axis_range, triple_distances);
+
+    coords[0].set_float (from_coord);
+    coords[1].set_float (to_coord);
+  }
+
+  HB_INTERNAL static int cmp (const void *pa, const void *pb)
+  {
+    const AxisValueMap *a = (const AxisValueMap *) pa;
+    const AxisValueMap *b = (const AxisValueMap *) pb;
+
+    int a_from = a->coords[0].to_int ();
+    int b_from = b->coords[0].to_int ();
+    if (a_from != b_from)
+      return a_from - b_from;
+
+    /* this should never be reached. according to the spec, all of the axis
+     * value map records for a given axis must have different fromCoord values
+     * */
+    int a_to = a->coords[1].to_int ();
+    int b_to = b->coords[1].to_int ();
+    return a_to - b_to;
+  }
+
+  bool serialize (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
   public:
   F2DOT14       coords[2];
 //   F2DOT14    fromCoord;      /* A normalized coordinate value obtained using
@@ -122,6 +181,78 @@
 
   int unmap (int value) const { return map (value, 1, 0); }
 
+  Triple unmap_axis_range (const Triple& axis_range) const
+  {
+    F2DOT14 val, unmapped_val;
+
+    val.set_float (axis_range.minimum);
+    unmapped_val.set_int (unmap (val.to_int ()));
+    float unmapped_min = unmapped_val.to_float ();
+
+    val.set_float (axis_range.middle);
+    unmapped_val.set_int (unmap (val.to_int ()));
+    float unmapped_middle = unmapped_val.to_float ();
+
+    val.set_float (axis_range.maximum);
+    unmapped_val.set_int (unmap (val.to_int ()));
+    float unmapped_max = unmapped_val.to_float ();
+
+    return Triple{unmapped_min, unmapped_middle, unmapped_max};
+  }
+
+  bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const
+  {
+    TRACE_SUBSET (this);
+    /* avar mapped normalized axis range*/
+    Triple *axis_range;
+    if (!c->plan->axes_location.has (axis_tag, &axis_range))
+      return c->serializer->embed (*this);
+
+    TripleDistances *axis_triple_distances;
+    if (!c->plan->axes_triple_distances.has (axis_tag, &axis_triple_distances))
+      return_trace (false);
+
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    Triple unmapped_range = unmap_axis_range (*axis_range);
+
+    /* create a vector of retained mappings and sort */
+    hb_vector_t value_mappings;
+    for (const auto& _ : as_array ())
+    {
+      if (_.is_outside_axis_range (unmapped_range))
+        continue;
+      AxisValueMap mapping;
+      mapping = _;
+      mapping.instantiate (*axis_range, unmapped_range, *axis_triple_distances);
+      /* (-1, -1), (0, 0), (1, 1) mappings will be added later, so avoid
+       * duplicates here */
+      if (mapping.must_include ())
+        continue;
+      value_mappings.push (std::move (mapping));
+    }
+
+    AxisValueMap m;
+    m.set_mapping (-1.f, -1.f);
+    value_mappings.push (m);
+
+    m.set_mapping (0.f, 0.f);
+    value_mappings.push (m);
+
+    m.set_mapping (1.f, 1.f);
+    value_mappings.push (m);
+
+    value_mappings.qsort ();
+
+    for (const auto& _ : value_mappings)
+    {
+      if (!_.serialize (c->serializer))
+        return_trace (false);
+    }
+    return_trace (c->serializer->check_assign (out->len, value_mappings.length, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   public:
   DEFINE_SIZE_ARRAY (2, *this);
 };
@@ -225,6 +356,39 @@
     }
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    unsigned retained_axis_count = c->plan->axes_index_map.get_population ();
+    if (!retained_axis_count) //all axes are pinned/dropped
+      return_trace (false);
+
+    avar *out = c->serializer->allocate_min ();
+    if (unlikely (!out)) return_trace (false);
+
+    out->version.major = 1;
+    out->version.minor = 0;
+    if (!c->serializer->check_assign (out->axisCount, retained_axis_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+
+    const hb_map_t& axes_index_map = c->plan->axes_index_map;
+    const SegmentMaps *map = &firstAxisSegmentMaps;
+    unsigned count = axisCount;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (axes_index_map.has (i))
+      {
+        hb_tag_t *axis_tag;
+        if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag))
+          return_trace (false);
+        if (!map->subset (c, *axis_tag))
+          return_trace (false);
+      }
+      map = &StructAfter (*map);
+    }
+    return_trace (true);
+  }
+
   protected:
   FixedVersion<>version;        /* Version of the avar table
                                  * initially set to 0x00010000u */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -27,6 +27,7 @@
 #define HB_OT_VAR_COMMON_HH
 
 #include "hb-ot-layout-common.hh"
+#include "hb-priority-queue.hh"
 
 
 namespace OT {
@@ -36,19 +37,14 @@
 {
   friend struct DeltaSetIndexMap;
 
+  unsigned get_size () const
+  { return min_size + mapCount * get_width (); }
+
   private:
   DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const
   {
     TRACE_SERIALIZE (this);
-    auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
-
-    unsigned total_size = min_size + mapCount * get_width ();
-    HBUINT8 *p = c->allocate_size (total_size);
-    if (unlikely (!p)) return_trace (nullptr);
-
-    hb_memcpy (p, this, HBUINT8::static_size * total_size);
-    return_trace (out);
+    return_trace (c->embed (this));
   }
 
   template 
@@ -69,14 +65,17 @@
     if (unlikely (!p)) return_trace (false);
     for (unsigned int i = 0; i < output_map.length; i++)
     {
-      unsigned int v = output_map[i];
-      unsigned int outer = v >> 16;
-      unsigned int inner = v & 0xFFFF;
-      unsigned int u = (outer << inner_bit_count) | inner;
-      for (unsigned int w = width; w > 0;)
+      unsigned int v = output_map.arrayZ[i];
+      if (v)
       {
-        p[--w] = u;
-        u >>= 8;
+        unsigned int outer = v >> 16;
+        unsigned int inner = v & 0xFFFF;
+        unsigned int u = (outer << inner_bit_count) | inner;
+        for (unsigned int w = width; w > 0;)
+        {
+          p[--w] = u;
+          u >>= 8;
+        }
       }
       p += width;
     }
@@ -232,7 +231,7 @@
   /* according to the spec, if colr table has varStore but does not have
    * varIdxMap, then an implicit identity mapping is used */
   float operator() (uint32_t varIdx, unsigned short offset = 0) const
-  { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); }
+  { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; }
 
   const VariationStore *varStore;
   const DeltaSetIndexMap *varIdxMap;
@@ -242,6 +241,7 @@
 /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */
 struct TupleVariationHeader
 {
+  friend struct tuple_delta_t;
   unsigned get_size (unsigned axis_count) const
   { return min_size + get_all_tuples (axis_count).get_size (); }
 
@@ -250,14 +250,67 @@
   const TupleVariationHeader &get_next (unsigned axis_count) const
   { return StructAtOffset (this, get_size (axis_count)); }
 
+  bool unpack_axis_tuples (unsigned axis_count,
+                           const hb_array_t shared_tuples,
+                           const hb_map_t *axes_old_index_tag_map,
+                           hb_hashmap_t& axis_tuples /* OUT */) const
+  {
+    const F2DOT14 *peak_tuple = nullptr;
+    if (has_peak ())
+      peak_tuple = get_peak_tuple (axis_count).arrayZ;
+    else
+    {
+      unsigned int index = get_index ();
+      if (unlikely ((index + 1) * axis_count > shared_tuples.length))
+        return false;
+      peak_tuple = shared_tuples.sub_array (axis_count * index, axis_count).arrayZ;
+    }
+
+    const F2DOT14 *start_tuple = nullptr;
+    const F2DOT14 *end_tuple = nullptr;
+    bool has_interm = has_intermediate ();
+
+    if (has_interm)
+    {
+      start_tuple = get_start_tuple (axis_count).arrayZ;
+      end_tuple = get_end_tuple (axis_count).arrayZ;
+    }
+
+    for (unsigned i = 0; i < axis_count; i++)
+    {
+      float peak = peak_tuple[i].to_float ();
+      if (peak == 0.f) continue;
+
+      hb_tag_t *axis_tag;
+      if (!axes_old_index_tag_map->has (i, &axis_tag))
+        return false;
+
+      float start, end;
+      if (has_interm)
+      {
+        start = start_tuple[i].to_float ();
+        end = end_tuple[i].to_float ();
+      }
+      else
+      {
+        start = hb_min (peak, 0.f);
+        end = hb_max (peak, 0.f);
+      }
+      axis_tuples.set (*axis_tag, Triple (start, peak, end));
+    }
+
+    return true;
+  }
+
   float calculate_scalar (hb_array_t coords, unsigned int coord_count,
                           const hb_array_t shared_tuples,
-                          const hb_vector_t *shared_tuple_active_idx = nullptr) const
+                          const hb_vector_t> *shared_tuple_active_idx = nullptr) const
   {
     const F2DOT14 *peak_tuple;
 
     unsigned start_idx = 0;
     unsigned end_idx = coord_count;
+    unsigned step = 1;
 
     if (has_peak ())
       peak_tuple = get_peak_tuple (coord_count).arrayZ;
@@ -270,11 +323,18 @@
 
       if (shared_tuple_active_idx)
       {
-        assert (index < shared_tuple_active_idx->length);
-        int v = (*shared_tuple_active_idx).arrayZ[index];
-        if (v != -1)
+        if (unlikely (index >= shared_tuple_active_idx->length))
+          return 0.f;
+        auto _ = (*shared_tuple_active_idx).arrayZ[index];
+        if (_.second != -1)
+        {
+          start_idx = _.first;
+          end_idx = _.second + 1;
+          step = _.second - _.first;
+        }
+        else if (_.first != -1)
         {
-          start_idx = v;
+          start_idx = _.first;
           end_idx = start_idx + 1;
         }
       }
@@ -290,7 +350,7 @@
     }
 
     float scalar = 1.f;
-    for (unsigned int i = start_idx; i < end_idx; i++)
+    for (unsigned int i = start_idx; i < end_idx; i += step)
     {
       int peak = peak_tuple[i].to_int ();
       if (!peak) continue;
@@ -332,6 +392,7 @@
       TupleIndexMask      = 0x0FFFu
     };
 
+    TuppleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
     DEFINE_SIZE_STATIC (2);
   };
 
@@ -364,6 +425,609 @@
   DEFINE_SIZE_MIN (4);
 };
 
+enum packed_delta_flag_t
+{
+  DELTAS_ARE_ZERO      = 0x80,
+  DELTAS_ARE_WORDS     = 0x40,
+  DELTA_RUN_COUNT_MASK = 0x3F
+};
+
+struct tuple_delta_t
+{
+  public:
+  hb_hashmap_t axis_tuples;
+
+  /* indices_length = point_count, indice[i] = 1 means point i is referenced */
+  hb_vector_t indices;
+
+  hb_vector_t deltas_x;
+  /* empty for cvar tuples */
+  hb_vector_t deltas_y;
+
+  /* compiled data: header and deltas
+   * compiled point data is saved in a hashmap within tuple_variations_t cause
+   * some point sets might be reused by different tuple variations */
+  hb_vector_t compiled_tuple_header;
+  hb_vector_t compiled_deltas;
+
+  /* compiled peak coords, empty for non-gvar tuples */
+  hb_vector_t compiled_peak_coords;
+
+  tuple_delta_t () = default;
+  tuple_delta_t (const tuple_delta_t& o) = default;
+
+  friend void swap (tuple_delta_t& a, tuple_delta_t& b)
+  {
+    hb_swap (a.axis_tuples, b.axis_tuples);
+    hb_swap (a.indices, b.indices);
+    hb_swap (a.deltas_x, b.deltas_x);
+    hb_swap (a.deltas_y, b.deltas_y);
+    hb_swap (a.compiled_tuple_header, b.compiled_tuple_header);
+    hb_swap (a.compiled_deltas, b.compiled_deltas);
+    hb_swap (a.compiled_peak_coords, b.compiled_peak_coords);
+  }
+
+  tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t ()
+  { hb_swap (*this, o); }
+
+  tuple_delta_t& operator = (tuple_delta_t&& o)
+  {
+    hb_swap (*this, o);
+    return *this;
+  }
+
+  void remove_axis (hb_tag_t axis_tag)
+  { axis_tuples.del (axis_tag); }
+
+  bool set_tent (hb_tag_t axis_tag, Triple tent)
+  { return axis_tuples.set (axis_tag, tent); }
+
+  tuple_delta_t& operator += (const tuple_delta_t& o)
+  {
+    unsigned num = indices.length;
+    for (unsigned i = 0; i < num; i++)
+    {
+      if (indices.arrayZ[i])
+      {
+        if (o.indices.arrayZ[i])
+        {
+          deltas_x[i] += o.deltas_x[i];
+          if (deltas_y && o.deltas_y)
+            deltas_y[i] += o.deltas_y[i];
+        }
+      }
+      else
+      {
+        if (!o.indices.arrayZ[i]) continue;
+        indices.arrayZ[i] = true;
+        deltas_x[i] = o.deltas_x[i];
+        if (deltas_y && o.deltas_y)
+          deltas_y[i] = o.deltas_y[i];
+      }
+    }
+    return *this;
+  }
+
+  tuple_delta_t& operator *= (float scalar)
+  {
+    if (scalar == 1.0f)
+      return *this;
+
+    unsigned num = indices.length;
+    for (unsigned i = 0; i < num; i++)
+    {
+      if (!indices.arrayZ[i]) continue;
+
+      deltas_x[i] *= scalar;
+      if (deltas_y)
+        deltas_y[i] *= scalar;
+    }
+    return *this;
+  }
+
+  hb_vector_t change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit,
+                                                          TripleDistances axis_triple_distances) const
+  {
+    hb_vector_t out;
+    Triple *tent;
+    if (!axis_tuples.has (axis_tag, &tent))
+    {
+      out.push (*this);
+      return out;
+    }
+
+    if ((tent->minimum < 0.f && tent->maximum > 0.f) ||
+        !(tent->minimum <= tent->middle && tent->middle <= tent->maximum))
+      return out;
+
+    if (tent->middle == 0.f)
+    {
+      out.push (*this);
+      return out;
+    }
+
+    result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances);
+    for (auto t : solutions)
+    {
+      tuple_delta_t new_var = *this;
+      if (t.second == Triple ())
+        new_var.remove_axis (axis_tag);
+      else
+        new_var.set_tent (axis_tag, t.second);
+
+      new_var *= t.first;
+      out.push (std::move (new_var));
+    }
+
+    return out;
+  }
+
+  bool compile_peak_coords (const hb_map_t& axes_index_map,
+                            const hb_map_t& axes_old_index_tag_map)
+  {
+    unsigned axis_count = axes_index_map.get_population ();
+    if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size)))
+      return false;
+
+    unsigned orig_axis_count = axes_old_index_tag_map.get_population ();
+    for (unsigned i = 0; i < orig_axis_count; i++)
+    {
+      if (!axes_index_map.has (i))
+        continue;
+
+      hb_tag_t axis_tag = axes_old_index_tag_map.get (i);
+      Triple *coords;
+      F2DOT14 peak_coord;
+      if (axis_tuples.has (axis_tag, &coords))
+        peak_coord.set_float (coords->middle);
+      else
+        peak_coord.set_int (0);
+
+      /* push F2DOT14 value into char vector */
+      int16_t val = peak_coord.to_int ();
+      compiled_peak_coords.push (static_cast (val >> 8));
+      compiled_peak_coords.push (static_cast (val & 0xFF));
+    }
+
+    return !compiled_peak_coords.in_error ();
+  }
+
+  /* deltas should be compiled already before we compile tuple
+   * variation header cause we need to fill in the size of the
+   * serialized data for this tuple variation */
+  bool compile_tuple_var_header (const hb_map_t& axes_index_map,
+                                 unsigned points_data_length,
+                                 const hb_map_t& axes_old_index_tag_map,
+                                 const hb_hashmap_t*, unsigned>* shared_tuples_idx_map)
+  {
+    if (!compiled_deltas) return false;
+
+    unsigned cur_axis_count = axes_index_map.get_population ();
+    /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */
+    unsigned alloc_len = 3 * cur_axis_count * (F2DOT14::static_size) + 4;
+    if (unlikely (!compiled_tuple_header.resize (alloc_len))) return false;
+
+    unsigned flag = 0;
+    /* skip the first 4 header bytes: variationDataSize+tupleIndex */
+    F2DOT14* p = reinterpret_cast (compiled_tuple_header.begin () + 4);
+    F2DOT14* end = reinterpret_cast (compiled_tuple_header.end ());
+    hb_array_t coords (p, end - p);
+
+    /* encode peak coords */
+    unsigned peak_count = 0;
+    unsigned *shared_tuple_idx;
+    if (shared_tuples_idx_map &&
+        shared_tuples_idx_map->has (&compiled_peak_coords, &shared_tuple_idx))
+    {
+      flag = *shared_tuple_idx;
+    }
+    else
+    {
+      peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map);
+      if (!peak_count) return false;
+    }
+
+    /* encode interim coords, it's optional so returned num could be 0 */
+    unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map);
+
+    /* pointdata length = 0 implies "use shared points" */
+    if (points_data_length)
+      flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers;
+
+    unsigned serialized_data_size = points_data_length + compiled_deltas.length;
+    TupleVariationHeader *o = reinterpret_cast (compiled_tuple_header.begin ());
+    o->varDataSize = serialized_data_size;
+    o->tupleIndex = flag;
+
+    unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size);
+    return compiled_tuple_header.resize (total_header_len);
+  }
+
+  unsigned encode_peak_coords (hb_array_t peak_coords,
+                               unsigned& flag,
+                               const hb_map_t& axes_index_map,
+                               const hb_map_t& axes_old_index_tag_map) const
+  {
+    unsigned orig_axis_count = axes_old_index_tag_map.get_population ();
+    auto it = peak_coords.iter ();
+    unsigned count = 0;
+    for (unsigned i = 0; i < orig_axis_count; i++)
+    {
+      if (!axes_index_map.has (i)) /* axis pinned */
+        continue;
+      hb_tag_t axis_tag = axes_old_index_tag_map.get (i);
+      Triple *coords;
+      if (!axis_tuples.has (axis_tag, &coords))
+        (*it).set_int (0);
+      else
+        (*it).set_float (coords->middle);
+      it++;
+      count++;
+    }
+    flag |= TupleVariationHeader::TuppleIndex::EmbeddedPeakTuple;
+    return count;
+  }
+
+  /* if no need to encode intermediate coords, then just return p */
+  unsigned encode_interm_coords (hb_array_t coords,
+                                 unsigned& flag,
+                                 const hb_map_t& axes_index_map,
+                                 const hb_map_t& axes_old_index_tag_map) const
+  {
+    unsigned orig_axis_count = axes_old_index_tag_map.get_population ();
+    unsigned cur_axis_count = axes_index_map.get_population ();
+
+    auto start_coords_iter = coords.sub_array (0, cur_axis_count).iter ();
+    auto end_coords_iter = coords.sub_array (cur_axis_count).iter ();
+    bool encode_needed = false;
+    unsigned count = 0;
+    for (unsigned i = 0; i < orig_axis_count; i++)
+    {
+      if (!axes_index_map.has (i)) /* axis pinned */
+        continue;
+      hb_tag_t axis_tag = axes_old_index_tag_map.get (i);
+      Triple *coords;
+      float min_val = 0.f, val = 0.f, max_val = 0.f;
+      if (axis_tuples.has (axis_tag, &coords))
+      {
+        min_val = coords->minimum;
+        val = coords->middle;
+        max_val = coords->maximum;
+      }
+
+      (*start_coords_iter).set_float (min_val);
+      (*end_coords_iter).set_float (max_val);
+
+      start_coords_iter++;
+      end_coords_iter++;
+      count += 2;
+      if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f))
+        encode_needed = true;
+    }
+
+    if (encode_needed)
+    {
+      flag |= TupleVariationHeader::TuppleIndex::IntermediateRegion;
+      return count;
+    }
+    return 0;
+  }
+
+  bool compile_deltas ()
+  {
+    hb_vector_t rounded_deltas;
+    if (unlikely (!rounded_deltas.alloc (indices.length)))
+      return false;
+
+    for (unsigned i = 0; i < indices.length; i++)
+    {
+      if (!indices[i]) continue;
+      int rounded_delta = (int) roundf (deltas_x[i]);
+      rounded_deltas.push (rounded_delta);
+    }
+
+    if (!rounded_deltas) return false;
+    /* allocate enough memories 3 * num_deltas */
+    unsigned alloc_len = 3 * rounded_deltas.length;
+    if (deltas_y)
+      alloc_len *= 2;
+
+    if (unlikely (!compiled_deltas.resize (alloc_len))) return false;
+
+    unsigned i = 0;
+    unsigned encoded_len = encode_delta_run (i, compiled_deltas.as_array (), rounded_deltas);
+
+    if (deltas_y)
+    {
+      /* reuse the rounded_deltas vector, check that deltas_y have the same num of deltas as deltas_x */
+      unsigned j = 0;
+      for (unsigned idx = 0; idx < indices.length; idx++)
+      {
+        if (!indices[idx]) continue;
+        int rounded_delta = (int) roundf (deltas_y[idx]);
+
+        if (j >= rounded_deltas.length) return false;
+
+        rounded_deltas[j++] = rounded_delta;
+      }
+
+      if (j != rounded_deltas.length) return false;
+      /* reset i because we reuse rounded_deltas for deltas_y */
+      i = 0;
+      encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas);
+    }
+    return compiled_deltas.resize (encoded_len);
+  }
+
+  unsigned encode_delta_run (unsigned& i,
+                             hb_array_t encoded_bytes,
+                             const hb_vector_t& deltas) const
+  {
+    unsigned num_deltas = deltas.length;
+    unsigned encoded_len = 0;
+    while (i < num_deltas)
+    {
+      int val = deltas[i];
+      if (val == 0)
+        encoded_len += encode_delta_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), deltas);
+      else if (val >= -128 && val <= 127)
+        encoded_len += encode_delta_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), deltas);
+      else
+        encoded_len += encode_delta_run_as_words (i, encoded_bytes.sub_array (encoded_len), deltas);
+    }
+    return encoded_len;
+  }
+
+  unsigned encode_delta_run_as_zeroes (unsigned& i,
+                                       hb_array_t encoded_bytes,
+                                       const hb_vector_t& deltas) const
+  {
+    unsigned num_deltas = deltas.length;
+    unsigned run_length = 0;
+    auto it = encoded_bytes.iter ();
+    unsigned encoded_len = 0;
+    while (i < num_deltas && deltas[i] == 0)
+    {
+      i++;
+      run_length++;
+    }
+
+    while (run_length >= 64)
+    {
+      *it++ = char (DELTAS_ARE_ZERO | 63);
+      run_length -= 64;
+      encoded_len++;
+    }
+
+    if (run_length)
+    {
+      *it++ = char (DELTAS_ARE_ZERO | (run_length - 1));
+      encoded_len++;
+    }
+    return encoded_len;
+  }
+
+  unsigned encode_delta_run_as_bytes (unsigned &i,
+                                      hb_array_t encoded_bytes,
+                                      const hb_vector_t& deltas) const
+  {
+    unsigned start = i;
+    unsigned num_deltas = deltas.length;
+    while (i < num_deltas)
+    {
+      int val = deltas[i];
+      if (val > 127 || val < -128)
+        break;
+
+      /* from fonttools: if there're 2 or more zeros in a sequence,
+       * it is better to start a new run to save bytes. */
+      if (val == 0 && i + 1 < num_deltas && deltas[i+1] == 0)
+        break;
+
+      i++;
+    }
+    unsigned run_length = i - start;
+
+    unsigned encoded_len = 0;
+    auto it = encoded_bytes.iter ();
+
+    while (run_length >= 64)
+    {
+      *it++ = 63;
+      encoded_len++;
+
+      for (unsigned j = 0; j < 64; j++)
+      {
+        *it++ = static_cast (deltas[start + j]);
+        encoded_len++;
+      }
+
+      start += 64;
+      run_length -= 64;
+    }
+
+    if (run_length)
+    {
+      *it++ = run_length - 1;
+      encoded_len++;
+
+      while (start < i)
+      {
+        *it++ = static_cast (deltas[start++]);
+        encoded_len++;
+      }
+    }
+
+    return encoded_len;
+  }
+
+  unsigned encode_delta_run_as_words (unsigned &i,
+                                      hb_array_t encoded_bytes,
+                                      const hb_vector_t& deltas) const
+  {
+    unsigned start = i;
+    unsigned num_deltas = deltas.length;
+    while (i < num_deltas)
+    {
+      int val = deltas[i];
+
+      /* start a new run for a single zero value*/
+      if (val == 0) break;
+
+      /* from fonttools: continue word-encoded run if there's only one
+       * single value in the range [-128, 127] because it is more compact.
+       * Only start a new run when there're 2 continuous such values. */
+      if (val >= -128 && val <= 127 &&
+          i + 1 < num_deltas &&
+          deltas[i+1] >= -128 && deltas[i+1] <= 127)
+        break;
+
+      i++;
+    }
+
+    unsigned run_length = i - start;
+    auto it = encoded_bytes.iter ();
+    unsigned encoded_len = 0;
+    while (run_length >= 64)
+    {
+      *it++ = (DELTAS_ARE_WORDS | 63);
+      encoded_len++;
+
+      for (unsigned j = 0; j < 64; j++)
+      {
+        int16_t delta_val = deltas[start + j];
+        *it++ = static_cast (delta_val >> 8);
+        *it++ = static_cast (delta_val & 0xFF);
+
+        encoded_len += 2;
+      }
+
+      start += 64;
+      run_length -= 64;
+    }
+
+    if (run_length)
+    {
+      *it++ = (DELTAS_ARE_WORDS | (run_length - 1));
+      encoded_len++;
+      while (start < i)
+      {
+        int16_t delta_val = deltas[start++];
+        *it++ = static_cast (delta_val >> 8);
+        *it++ = static_cast (delta_val & 0xFF);
+
+        encoded_len += 2;
+      }
+    }
+    return encoded_len;
+  }
+
+  bool calc_inferred_deltas (const contour_point_vector_t& orig_points)
+  {
+    unsigned point_count = orig_points.length;
+    if (point_count != indices.length)
+      return false;
+
+    unsigned ref_count = 0;
+    hb_vector_t end_points;
+
+    for (unsigned i = 0; i < point_count; i++)
+    {
+      if (indices.arrayZ[i])
+        ref_count++;
+      if (orig_points.arrayZ[i].is_end_point)
+        end_points.push (i);
+    }
+    /* all points are referenced, nothing to do */
+    if (ref_count == point_count)
+      return true;
+    if (unlikely (end_points.in_error ())) return false;
+
+    hb_set_t inferred_idxes;
+    unsigned start_point = 0;
+    for (unsigned end_point : end_points)
+    {
+      /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
+      unsigned unref_count = 0;
+      for (unsigned i = start_point; i < end_point + 1; i++)
+        unref_count += indices.arrayZ[i];
+      unref_count = (end_point - start_point + 1) - unref_count;
+
+      unsigned j = start_point;
+      if (unref_count == 0 || unref_count > end_point - start_point)
+        goto no_more_gaps;
+      for (;;)
+      {
+        /* Locate the next gap of unreferenced points between two referenced points prev and next.
+         * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
+         */
+        unsigned int prev, next, i;
+        for (;;)
+        {
+          i = j;
+          j = next_index (i, start_point, end_point);
+          if (indices.arrayZ[i] && !indices.arrayZ[j]) break;
+        }
+        prev = j = i;
+        for (;;)
+        {
+          i = j;
+          j = next_index (i, start_point, end_point);
+          if (!indices.arrayZ[i] && indices.arrayZ[j]) break;
+        }
+        next = j;
+       /* Infer deltas for all unref points in the gap between prev and next */
+        i = prev;
+        for (;;)
+        {
+          i = next_index (i, start_point, end_point);
+          if (i == next) break;
+          deltas_x.arrayZ[i] = infer_delta (orig_points.arrayZ[i].x, orig_points.arrayZ[prev].x, orig_points.arrayZ[next].x,
+                                            deltas_x.arrayZ[prev], deltas_x.arrayZ[next]);
+          deltas_y.arrayZ[i] = infer_delta (orig_points.arrayZ[i].y, orig_points.arrayZ[prev].y, orig_points.arrayZ[next].y,
+                                            deltas_y.arrayZ[prev], deltas_y.arrayZ[next]);
+          inferred_idxes.add (i);
+          if (--unref_count == 0) goto no_more_gaps;
+        }
+      }
+    no_more_gaps:
+      start_point = end_point + 1;
+    }
+
+    for (unsigned i = 0; i < point_count; i++)
+    {
+      /* if points are not referenced and deltas are not inferred, set to 0.
+       * reference all points for gvar */
+      if ( !indices[i])
+      {
+        if (!inferred_idxes.has (i))
+        {
+          deltas_x.arrayZ[i] = 0.f;
+          deltas_y.arrayZ[i] = 0.f;
+        }
+        indices[i] = true;
+      }
+    }
+    return true;
+  }
+
+  static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta)
+  {
+    if (prev_val == next_val)
+      return (prev_delta == next_delta) ? prev_delta : 0.f;
+    else if (target_val <= hb_min (prev_val, next_val))
+      return (prev_val < next_val) ? prev_delta : next_delta;
+    else if (target_val >= hb_max (prev_val, next_val))
+      return (prev_val > next_val) ? prev_delta : next_delta;
+
+    float r = (target_val - prev_val) / (next_val - prev_val);
+    return prev_delta + r * (next_delta - prev_delta);
+  }
+
+  static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end)
+  { return (i >= end) ? start : (i + 1); }
+};
+
 struct TupleVariationData
 {
   bool sanitize (hb_sanitize_context_t *c) const
@@ -377,7 +1041,7 @@
   unsigned get_size (unsigned axis_count) const
   {
     unsigned total_size = min_size;
-    unsigned count = tupleVarCount;
+    unsigned count = tupleVarCount.get_count ();
     const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header());
     for (unsigned i = 0; i < count; i++)
     {
@@ -391,8 +1055,485 @@
   const TupleVariationHeader &get_tuple_var_header (void) const
   { return StructAfter (data); }
 
+  struct tuple_iterator_t;
+  struct tuple_variations_t
+  {
+    hb_vector_t tuple_vars;
+
+    private:
+    /* referenced point set->compiled point data map */
+    hb_hashmap_t*, hb_bytes_t> point_data_map;
+    /* referenced point set-> count map, used in finding shared points */
+    hb_hashmap_t*, unsigned> point_set_count_map;
+
+    /* empty for non-gvar tuples.
+     * shared_points_bytes is just a copy of some value in the point_data_map,
+     * which will be freed during map destruction. Save it for serialization, so
+     * no need to do find_shared_points () again */
+    hb_bytes_t shared_points_bytes;
+
+    /* total compiled byte size as TupleVariationData format, initialized to its
+     * min_size: 4 */
+    unsigned compiled_byte_size = 4;
+
+    public:
+    tuple_variations_t () = default;
+    tuple_variations_t (const tuple_variations_t&) = delete;
+    tuple_variations_t& operator=(const tuple_variations_t&) = delete;
+    tuple_variations_t (tuple_variations_t&&) = default;
+    tuple_variations_t& operator=(tuple_variations_t&&) = default;
+    ~tuple_variations_t () { fini (); }
+    void fini ()
+    {
+      for (auto _ : point_data_map.values ())
+        _.fini ();
+
+      point_set_count_map.fini ();
+      tuple_vars.fini ();
+    }
+
+    explicit operator bool () const { return bool (tuple_vars); }
+    unsigned get_var_count () const
+    {
+      unsigned count = tuple_vars.length;
+      if (shared_points_bytes.length)
+        count |= TupleVarCount::SharedPointNumbers;
+      return count;
+    }
+
+    unsigned get_compiled_byte_size () const
+    { return compiled_byte_size; }
+
+    bool create_from_tuple_var_data (tuple_iterator_t iterator,
+                                     unsigned tuple_var_count,
+                                     unsigned point_count,
+                                     bool is_gvar,
+                                     const hb_map_t *axes_old_index_tag_map,
+                                     const hb_vector_t &shared_indices,
+                                     const hb_array_t shared_tuples)
+    {
+      do
+      {
+        const HBUINT8 *p = iterator.get_serialized_data ();
+        unsigned int length = iterator.current_tuple->get_data_size ();
+        if (unlikely (!iterator.var_data_bytes.check_range (p, length)))
+        { fini (); return false; }
+
+        hb_hashmap_t axis_tuples;
+        if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples)
+            || axis_tuples.is_empty ())
+        { fini (); return false; }
+
+        hb_vector_t private_indices;
+        bool has_private_points = iterator.current_tuple->has_private_points ();
+        const HBUINT8 *end = p + length;
+        if (has_private_points &&
+            !TupleVariationData::unpack_points (p, private_indices, end))
+        { fini (); return false; }
+
+        const hb_vector_t &indices = has_private_points ? private_indices : shared_indices;
+        bool apply_to_all = (indices.length == 0);
+        unsigned num_deltas = apply_to_all ? point_count : indices.length;
+
+        hb_vector_t deltas_x;
+
+        if (unlikely (!deltas_x.resize (num_deltas, false) ||
+                      !TupleVariationData::unpack_deltas (p, deltas_x, end)))
+        { fini (); return false; }
+
+        hb_vector_t deltas_y;
+        if (is_gvar)
+        {
+          if (unlikely (!deltas_y.resize (num_deltas, false) ||
+                        !TupleVariationData::unpack_deltas (p, deltas_y, end)))
+          { fini (); return false; }
+        }
+
+        tuple_delta_t var;
+        var.axis_tuples = std::move (axis_tuples);
+        if (unlikely (!var.indices.resize (point_count) ||
+                      !var.deltas_x.resize (point_count, false)))
+        { fini (); return false; }
+
+        if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false)))
+        { fini (); return false; }
+
+        for (unsigned i = 0; i < num_deltas; i++)
+        {
+          unsigned idx = apply_to_all ? i : indices[i];
+          if (idx >= point_count) continue;
+          var.indices[idx] = true;
+          var.deltas_x[idx] = static_cast (deltas_x[i]);
+          if (is_gvar)
+            var.deltas_y[idx] = static_cast (deltas_y[i]);
+        }
+        tuple_vars.push (std::move (var));
+      } while (iterator.move_to_next ());
+      return true;
+    }
+
+    bool create_from_item_var_data (const VarData &var_data,
+                                    const hb_vector_t>& regions,
+                                    const hb_map_t& axes_old_index_tag_map,
+                                    const hb_inc_bimap_t* inner_map = nullptr)
+    {
+      /* NULL offset, to keep original varidx valid, just return */
+      if (&var_data == &Null (VarData))
+        return true;
+
+      unsigned num_regions = var_data.get_region_index_count ();
+      if (!tuple_vars.alloc (num_regions)) return false;
+
+      unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count ();
+      unsigned row_size = var_data.get_row_size ();
+      const HBUINT8 *delta_bytes = var_data.get_delta_bytes ();
+
+      for (unsigned r = 0; r < num_regions; r++)
+      {
+        /* In VarData, deltas are organized in rows, convert them into
+         * column(region) based tuples, resize deltas_x first */
+        tuple_delta_t tuple;
+        if (!tuple.deltas_x.resize (item_count, false) ||
+            !tuple.indices.resize (item_count, false))
+          return false;
+
+        for (unsigned i = 0; i < item_count; i++)
+        {
+          tuple.indices.arrayZ[i] = true;
+          tuple.deltas_x.arrayZ[i] = var_data.get_item_delta_fast (inner_map ? inner_map->backward (i) : i,
+                                                                   r, delta_bytes, row_size);
+        }
+
+        unsigned region_index = var_data.get_region_index (r);
+        if (region_index >= regions.length) return false;
+        tuple.axis_tuples = regions.arrayZ[region_index];
+
+        tuple_vars.push (std::move (tuple));
+      }
+      return !tuple_vars.in_error ();
+    }
+
+    private:
+    static int _cmp_axis_tag (const void *pa, const void *pb)
+    {
+      const hb_tag_t *a = (const hb_tag_t*) pa;
+      const hb_tag_t *b = (const hb_tag_t*) pb;
+      return (int)(*a) - (int)(*b);
+    }
+
+    bool change_tuple_variations_axis_limits (const hb_hashmap_t& normalized_axes_location,
+                                              const hb_hashmap_t& axes_triple_distances)
+    {
+      /* sort axis_tag/axis_limits, make result deterministic */
+      hb_vector_t axis_tags;
+      if (!axis_tags.alloc (normalized_axes_location.get_population ()))
+        return false;
+      for (auto t : normalized_axes_location.keys ())
+        axis_tags.push (t);
+
+      axis_tags.qsort (_cmp_axis_tag);
+      for (auto axis_tag : axis_tags)
+      {
+        Triple *axis_limit;
+        if (!normalized_axes_location.has (axis_tag, &axis_limit))
+          return false;
+        TripleDistances axis_triple_distances{1.f, 1.f};
+        if (axes_triple_distances.has (axis_tag))
+          axis_triple_distances = axes_triple_distances.get (axis_tag);
+
+        hb_vector_t new_vars;
+        for (const tuple_delta_t& var : tuple_vars)
+        {
+          hb_vector_t out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances);
+          if (!out) continue;
+
+          unsigned new_len = new_vars.length + out.length;
+
+          if (unlikely (!new_vars.alloc (new_len, false)))
+          { fini (); return false;}
+
+          for (unsigned i = 0; i < out.length; i++)
+            new_vars.push (std::move (out[i]));
+        }
+        tuple_vars.fini ();
+        tuple_vars = std::move (new_vars);
+      }
+      return true;
+    }
+
+    /* merge tuple variations with overlapping tents */
+    void merge_tuple_variations ()
+    {
+      hb_vector_t new_vars;
+      hb_hashmap_t*, unsigned> m;
+      unsigned i = 0;
+      for (const tuple_delta_t& var : tuple_vars)
+      {
+        /* if all axes are pinned, drop the tuple variation */
+        if (var.axis_tuples.is_empty ()) continue;
+
+        unsigned *idx;
+        if (m.has (&(var.axis_tuples), &idx))
+        {
+          new_vars[*idx] += var;
+        }
+        else
+        {
+          new_vars.push (var);
+          m.set (&(var.axis_tuples), i);
+          i++;
+        }
+      }
+      tuple_vars.fini ();
+      tuple_vars = std::move (new_vars);
+    }
+
+    hb_bytes_t compile_point_set (const hb_vector_t &point_indices)
+    {
+      unsigned num_points = 0;
+      for (bool i : point_indices)
+        if (i) num_points++;
+
+      unsigned indices_length = point_indices.length;
+      /* If the points set consists of all points in the glyph, it's encoded with a
+       * single zero byte */
+      if (num_points == indices_length)
+      {
+        char *p = (char *) hb_calloc (1, sizeof (char));
+        if (unlikely (!p)) return hb_bytes_t ();
+
+        return hb_bytes_t (p, 1);
+      }
+
+      /* allocate enough memories: 2 bytes for count + 3 bytes for each point */
+      unsigned num_bytes = 2 + 3 *num_points;
+      char *p = (char *) hb_calloc (num_bytes, sizeof (char));
+      if (unlikely (!p)) return hb_bytes_t ();
+
+      unsigned pos = 0;
+      /* binary data starts with the total number of reference points */
+      if (num_points < 0x80)
+        p[pos++] = num_points;
+      else
+      {
+        p[pos++] = ((num_points >> 8) | 0x80);
+        p[pos++] = num_points & 0xFF;
+      }
+
+      const unsigned max_run_length = 0x7F;
+      unsigned i = 0;
+      unsigned last_value = 0;
+      unsigned num_encoded = 0;
+      while (i < indices_length && num_encoded < num_points)
+      {
+        unsigned run_length = 0;
+        unsigned header_pos = pos;
+        p[pos++] = 0;
+
+        bool use_byte_encoding = false;
+        bool new_run = true;
+        while (i < indices_length && num_encoded < num_points &&
+               run_length <= max_run_length)
+        {
+          // find out next referenced point index
+          while (i < indices_length && !point_indices[i])
+            i++;
+
+          if (i >= indices_length) break;
+
+          unsigned cur_value = i;
+          unsigned delta = cur_value - last_value;
+
+          if (new_run)
+          {
+            use_byte_encoding = (delta <= 0xFF);
+            new_run = false;
+          }
+
+          if (use_byte_encoding && delta > 0xFF)
+            break;
+
+          if (use_byte_encoding)
+            p[pos++] = delta;
+          else
+          {
+            p[pos++] = delta >> 8;
+            p[pos++] = delta & 0xFF;
+          }
+          i++;
+          last_value = cur_value;
+          run_length++;
+          num_encoded++;
+        }
+
+        if (use_byte_encoding)
+          p[header_pos] = run_length - 1;
+        else
+          p[header_pos] = (run_length - 1) | 0x80;
+      }
+      return hb_bytes_t (p, pos);
+    }
+
+    /* compile all point set and store byte data in a point_set->hb_bytes_t hashmap,
+     * also update point_set->count map, which will be used in finding shared
+     * point set*/
+    bool compile_all_point_sets ()
+    {
+      for (const auto& tuple: tuple_vars)
+      {
+        const hb_vector_t* points_set = &(tuple.indices);
+        if (point_data_map.has (points_set))
+        {
+          unsigned *count;
+          if (unlikely (!point_set_count_map.has (points_set, &count) ||
+                        !point_set_count_map.set (points_set, (*count) + 1)))
+            return false;
+          continue;
+        }
+
+        hb_bytes_t compiled_data = compile_point_set (*points_set);
+        if (unlikely (compiled_data == hb_bytes_t ()))
+          return false;
+
+        if (!point_data_map.set (points_set, compiled_data) ||
+            !point_set_count_map.set (points_set, 1))
+          return false;
+      }
+      return true;
+    }
+
+    /* find shared points set which saves most bytes */
+    hb_bytes_t find_shared_points ()
+    {
+      unsigned max_saved_bytes = 0;
+      hb_bytes_t res{};
+
+      for (const auto& _ : point_data_map.iter ())
+      {
+        const hb_vector_t* points_set = _.first;
+        unsigned data_length = _.second.length;
+        unsigned *count;
+        if (unlikely (!point_set_count_map.has (points_set, &count) ||
+                      *count <= 1))
+          return hb_bytes_t ();
+
+        unsigned saved_bytes = data_length * ((*count) -1);
+        if (saved_bytes > max_saved_bytes)
+        {
+          max_saved_bytes = saved_bytes;
+          res = _.second;
+        }
+      }
+      return res;
+    }
+
+    bool calc_inferred_deltas (contour_point_vector_t& contour_points)
+    {
+      for (tuple_delta_t& var : tuple_vars)
+        if (!var.calc_inferred_deltas (contour_points))
+          return false;
+
+      return true;
+    }
+
+    public:
+    bool instantiate (const hb_hashmap_t& normalized_axes_location,
+                      const hb_hashmap_t& axes_triple_distances,
+                      contour_point_vector_t* contour_points = nullptr)
+    {
+      if (!tuple_vars) return true;
+      if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances))
+        return false;
+      /* compute inferred deltas only for gvar */
+      if (contour_points)
+        if (!calc_inferred_deltas (*contour_points))
+          return false;
+
+      merge_tuple_variations ();
+      return !tuple_vars.in_error ();
+    }
+
+    bool compile_bytes (const hb_map_t& axes_index_map,
+                        const hb_map_t& axes_old_index_tag_map,
+                        bool use_shared_points,
+                        const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr)
+    {
+      // compile points set and store data in hashmap
+      if (!compile_all_point_sets ())
+        return false;
+
+      if (use_shared_points)
+      {
+        shared_points_bytes = find_shared_points ();
+        compiled_byte_size += shared_points_bytes.length;
+      }
+      // compile delta and tuple var header for each tuple variation
+      for (auto& tuple: tuple_vars)
+      {
+        const hb_vector_t* points_set = &(tuple.indices);
+        hb_bytes_t *points_data;
+        if (unlikely (!point_data_map.has (points_set, &points_data)))
+          return false;
+
+        if (!tuple.compile_deltas ())
+          return false;
+
+        unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0;
+        if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map,
+                                             shared_tuples_idx_map))
+          return false;
+        compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length;
+      }
+      return true;
+    }
+
+    bool serialize_var_headers (hb_serialize_context_t *c, unsigned& total_header_len) const
+    {
+      TRACE_SERIALIZE (this);
+      for (const auto& tuple: tuple_vars)
+      {
+        tuple.compiled_tuple_header.as_array ().copy (c);
+        if (c->in_error ()) return_trace (false);
+        total_header_len += tuple.compiled_tuple_header.length;
+      }
+      return_trace (true);
+    }
+
+    bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const
+    {
+      TRACE_SERIALIZE (this);
+      if (is_gvar)
+        shared_points_bytes.copy (c);
+
+      for (const auto& tuple: tuple_vars)
+      {
+        const hb_vector_t* points_set = &(tuple.indices);
+        hb_bytes_t *point_data;
+        if (!point_data_map.has (points_set, &point_data))
+          return_trace (false);
+
+        if (!is_gvar || *point_data != shared_points_bytes)
+          point_data->copy (c);
+
+        tuple.compiled_deltas.as_array ().copy (c);
+        if (c->in_error ()) return_trace (false);
+      }
+
+      /* padding for gvar */
+      if (is_gvar && (compiled_byte_size % 2))
+      {
+        HBUINT8 pad;
+        pad = 0;
+        if (!c->embed (pad)) return_trace (false);
+      }
+      return_trace (true);
+    }
+  };
+
   struct tuple_iterator_t
   {
+    unsigned get_axis_count () const { return axis_count; }
+
     void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_, const void *table_base_)
     {
       var_data_bytes = var_data_bytes_;
@@ -516,13 +1657,6 @@
                              hb_vector_t &deltas /* IN/OUT */,
                              const HBUINT8 *end)
   {
-    enum packed_delta_flag_t
-    {
-      DELTAS_ARE_ZERO      = 0x80,
-      DELTAS_ARE_WORDS     = 0x40,
-      DELTA_RUN_COUNT_MASK = 0x3F
-    };
-
     unsigned i = 0;
     unsigned count = deltas.length;
     while (i < count)
@@ -560,11 +1694,55 @@
 
   bool has_data () const { return tupleVarCount; }
 
+  bool decompile_tuple_variations (unsigned point_count,
+                                   bool is_gvar,
+                                   tuple_iterator_t iterator,
+                                   const hb_map_t *axes_old_index_tag_map,
+                                   const hb_vector_t &shared_indices,
+                                   const hb_array_t shared_tuples,
+                                   tuple_variations_t& tuple_variations /* OUT */) const
+  {
+    return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount,
+                                                        point_count, is_gvar,
+                                                        axes_old_index_tag_map,
+                                                        shared_indices,
+                                                        shared_tuples);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  bool is_gvar,
+                  const tuple_variations_t& tuple_variations) const
+  {
+    TRACE_SERIALIZE (this);
+    /* empty tuple variations, just return and skip serialization. */
+    if (!tuple_variations) return_trace (true);
+
+    auto *out = c->start_embed (this);
+    if (unlikely (!c->extend_min (out))) return_trace (false);
+
+    if (!c->check_assign (out->tupleVarCount, tuple_variations.get_var_count (),
+                          HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+
+    unsigned total_header_len = 0;
+
+    if (!tuple_variations.serialize_var_headers (c, total_header_len))
+      return_trace (false);
+
+    unsigned data_offset = min_size + total_header_len;
+    if (!is_gvar) data_offset += 4;
+    if (!c->check_assign (out->data, data_offset, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+
+    return tuple_variations.serialize_var_data (c, is_gvar);
+  }
+
   protected:
   struct TupleVarCount : HBUINT16
   {
+    friend struct tuple_variations_t;
     bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
     unsigned int get_count () const { return (*this) & CountMask; }
+    TupleVarCount& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
+    explicit operator bool () const { return get_count (); }
 
     protected:
     enum Flags
@@ -588,6 +1766,463 @@
   DEFINE_SIZE_MIN (4);
 };
 
+using tuple_variations_t = TupleVariationData::tuple_variations_t;
+struct item_variations_t
+{
+  using region_t = const hb_hashmap_t*;
+  private:
+  /* each subtable is decompiled into a tuple_variations_t, in which all tuples
+   * have the same num of deltas (rows) */
+  hb_vector_t vars;
+
+  /* original region list, decompiled from item varstore, used when rebuilding
+   * region list after instantiation */
+  hb_vector_t> orig_region_list;
+
+  /* region list: vector of Regions, maintain the original order for the regions
+   * that existed before instantiate (), append the new regions at the end.
+   * Regions are stored in each tuple already, save pointers only.
+   * When converting back to item varstore, unused regions will be pruned */
+  hb_vector_t region_list;
+
+  /* region -> idx map after instantiation and pruning unused regions */
+  hb_hashmap_t region_map;
+
+  /* all delta rows after instantiation */
+  hb_vector_t> delta_rows;
+  /* final optimized vector of encoding objects used to assemble the varstore */
+  hb_vector_t encodings;
+
+  /* old varidxes -> new var_idxes map */
+  hb_map_t varidx_map;
+
+  /* has long words */
+  bool has_long = false;
+
+  public:
+  bool has_long_word () const
+  { return has_long; }
+
+  const hb_vector_t& get_region_list () const
+  { return region_list; }
+
+  const hb_vector_t& get_vardata_encodings () const
+  { return encodings; }
+
+  const hb_map_t& get_varidx_map () const
+  { return varidx_map; }
+
+  bool instantiate (const VariationStore& varStore,
+                    const hb_subset_plan_t *plan,
+                    bool optimize=true,
+                    bool use_no_variation_idx=true,
+                    const hb_array_t  inner_maps = hb_array_t ())
+  {
+    if (!create_from_item_varstore (varStore, plan->axes_old_index_tag_map, inner_maps))
+      return false;
+    if (!instantiate_tuple_vars (plan->axes_location, plan->axes_triple_distances))
+      return false;
+    return as_item_varstore (optimize, use_no_variation_idx);
+  }
+
+  /* keep below APIs public only for unit test: test-item-varstore */
+  bool create_from_item_varstore (const VariationStore& varStore,
+                                  const hb_map_t& axes_old_index_tag_map,
+                                  const hb_array_t  inner_maps = hb_array_t ())
+  {
+    const VarRegionList& regionList = varStore.get_region_list ();
+    if (!regionList.get_var_regions (axes_old_index_tag_map, orig_region_list))
+      return false;
+
+    unsigned num_var_data = varStore.get_sub_table_count ();
+    if (inner_maps && inner_maps.length != num_var_data) return false;
+    if (!vars.alloc (num_var_data)) return false;
+
+    for (unsigned i = 0; i < num_var_data; i++)
+    {
+      if (inner_maps && !inner_maps.arrayZ[i].get_population ())
+          continue;
+      tuple_variations_t var_data_tuples;
+      if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i),
+                                                      orig_region_list,
+                                                      axes_old_index_tag_map,
+                                                      inner_maps ? &(inner_maps.arrayZ[i]) : nullptr))
+        return false;
+
+      vars.push (std::move (var_data_tuples));
+    }
+    return !vars.in_error ();
+  }
+
+  bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location,
+                               const hb_hashmap_t& axes_triple_distances)
+  {
+    for (tuple_variations_t& tuple_vars : vars)
+      if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances))
+        return false;
+
+    if (!build_region_list ()) return false;
+    return true;
+  }
+
+  bool build_region_list ()
+  {
+    /* scan all tuples and collect all unique regions, prune unused regions */
+    hb_hashmap_t all_regions;
+    hb_hashmap_t used_regions;
+
+    /* use a vector when inserting new regions, make result deterministic */
+    hb_vector_t all_unique_regions;
+    for (const tuple_variations_t& sub_table : vars)
+    {
+      for (const tuple_delta_t& tuple : sub_table.tuple_vars)
+      {
+        region_t r = &(tuple.axis_tuples);
+        if (!used_regions.has (r))
+        {
+          bool all_zeros = true;
+          for (float d : tuple.deltas_x)
+          {
+            int delta = (int) roundf (d);
+            if (delta != 0)
+            {
+              all_zeros = false;
+              break;
+            }
+          }
+          if (!all_zeros)
+          {
+            if (!used_regions.set (r, 1))
+              return false;
+          }
+        }
+        if (all_regions.has (r))
+          continue;
+        if (!all_regions.set (r, 1))
+          return false;
+        all_unique_regions.push (r);
+      }
+    }
+
+    if (!all_regions || !all_unique_regions) return false;
+    if (!region_list.alloc (all_regions.get_population ()))
+      return false;
+
+    unsigned idx = 0;
+    /* append the original regions that pre-existed */
+    for (const auto& r : orig_region_list)
+    {
+      if (!all_regions.has (&r) || !used_regions.has (&r))
+        continue;
+
+      region_list.push (&r);
+      if (!region_map.set (&r, idx))
+        return false;
+      all_regions.del (&r);
+      idx++;
+    }
+
+    /* append the new regions at the end */
+    for (const auto& r: all_unique_regions)
+    {
+      if (!all_regions.has (r) || !used_regions.has (r))
+        continue;
+      region_list.push (r);
+      if (!region_map.set (r, idx))
+        return false;
+      all_regions.del (r);
+      idx++;
+    }
+    return (!region_list.in_error ()) && (!region_map.in_error ());
+  }
+
+  /* main algorithm ported from fonttools VarStore_optimize() method, optimize
+   * varstore by default */
+
+  struct combined_gain_idx_tuple_t
+  {
+    int gain;
+    unsigned idx_1;
+    unsigned idx_2;
+
+    combined_gain_idx_tuple_t () = default;
+    combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j)
+        :gain (gain_), idx_1 (i), idx_2 (j) {}
+
+    bool operator < (const combined_gain_idx_tuple_t& o)
+    {
+      if (gain != o.gain)
+        return gain < o.gain;
+
+      if (idx_1 != o.idx_1)
+        return idx_1 < o.idx_1;
+
+      return idx_2 < o.idx_2;
+    }
+
+    bool operator <= (const combined_gain_idx_tuple_t& o)
+    {
+      if (*this < o) return true;
+      return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2;
+    }
+  };
+
+  bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true)
+  {
+    if (!region_list) return false;
+    unsigned num_cols = region_list.length;
+    /* pre-alloc a 2D vector for all sub_table's VarData rows */
+    unsigned total_rows = 0;
+    for (unsigned major = 0; major < vars.length; major++)
+    {
+      const tuple_variations_t& tuples = vars[major];
+      /* all tuples in each sub_table should have same num of deltas(num rows) */
+      total_rows += tuples.tuple_vars[0].deltas_x.length;
+    }
+
+    if (!delta_rows.resize (total_rows)) return false;
+    /* init all rows to [0]*num_cols */
+    for (unsigned i = 0; i < total_rows; i++)
+      if (!(delta_rows[i].resize (num_cols))) return false;
+
+    /* old VarIdxes -> full encoding_row mapping */
+    hb_hashmap_t*> front_mapping;
+    unsigned start_row = 0;
+    hb_vector_t encoding_objs;
+    hb_hashmap_t, unsigned> chars_idx_map;
+
+    /* delta_rows map, used for filtering out duplicate rows */
+    hb_hashmap_t*, unsigned> delta_rows_map;
+    for (unsigned major = 0; major < vars.length; major++)
+    {
+      /* deltas are stored in tuples(column based), convert them back into items
+       * (row based) delta */
+      const tuple_variations_t& tuples = vars[major];
+      unsigned num_rows = tuples.tuple_vars[0].deltas_x.length;
+      for (const tuple_delta_t& tuple: tuples.tuple_vars)
+      {
+        if (tuple.deltas_x.length != num_rows)
+          return false;
+
+        /* skip unused regions */
+        unsigned *col_idx;
+        if (!region_map.has (&(tuple.axis_tuples), &col_idx))
+          continue;
+
+        for (unsigned i = 0; i < num_rows; i++)
+        {
+          int rounded_delta = roundf (tuple.deltas_x[i]);
+          delta_rows[start_row + i][*col_idx] += rounded_delta;
+          if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535))
+            has_long = true;
+        }
+      }
+
+      if (!optimize)
+      {
+        /* assemble a delta_row_encoding_t for this subtable, skip optimization so
+         * chars is not initialized, we only need delta rows for serialization */
+        delta_row_encoding_t obj;
+        for (unsigned r = start_row; r < start_row + num_rows; r++)
+          obj.add_row (&(delta_rows.arrayZ[r]));
+
+        encodings.push (std::move (obj));
+        start_row += num_rows;
+        continue;
+      }
+
+      for (unsigned minor = 0; minor < num_rows; minor++)
+      {
+        const hb_vector_t& row = delta_rows[start_row + minor];
+        if (use_no_variation_idx)
+        {
+          bool all_zeros = true;
+          for (int delta : row)
+          {
+            if (delta != 0)
+            {
+              all_zeros = false;
+              break;
+            }
+          }
+          if (all_zeros)
+            continue;
+        }
+
+        if (!front_mapping.set ((major<<16) + minor, &row))
+          return false;
+
+        hb_vector_t chars = delta_row_encoding_t::get_row_chars (row);
+        if (!chars) return false;
+
+        if (delta_rows_map.has (&row))
+          continue;
+
+        delta_rows_map.set (&row, 1);
+        unsigned *obj_idx;
+        if (chars_idx_map.has (chars, &obj_idx))
+        {
+          delta_row_encoding_t& obj = encoding_objs[*obj_idx];
+          if (!obj.add_row (&row))
+            return false;
+        }
+        else
+        {
+          if (!chars_idx_map.set (chars, encoding_objs.length))
+            return false;
+          delta_row_encoding_t obj (std::move (chars), &row);
+          encoding_objs.push (std::move (obj));
+        }
+      }
+
+      start_row += num_rows;
+    }
+
+    /* return directly if no optimization, maintain original VariationIndex so
+     * varidx_map would be empty */
+    if (!optimize) return !encodings.in_error ();
+
+    /* sort encoding_objs */
+    encoding_objs.qsort ();
+
+    /* main algorithm: repeatedly pick 2 best encodings to combine, and combine
+     * them */
+    hb_priority_queue_t queue;
+    unsigned num_todos = encoding_objs.length;
+    for (unsigned i = 0; i < num_todos; i++)
+    {
+      for (unsigned j = i + 1; j < num_todos; j++)
+      {
+        int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]);
+        if (combining_gain > 0)
+          queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0);
+      }
+    }
+
+    hb_set_t removed_todo_idxes;
+    while (queue)
+    {
+      auto t = queue.pop_minimum ().first;
+      unsigned i = t.idx_1;
+      unsigned j = t.idx_2;
+
+      if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j))
+        continue;
+
+      delta_row_encoding_t& encoding = encoding_objs.arrayZ[i];
+      delta_row_encoding_t& other_encoding = encoding_objs.arrayZ[j];
+
+      removed_todo_idxes.add (i);
+      removed_todo_idxes.add (j);
+
+      hb_vector_t combined_chars;
+      if (!combined_chars.alloc (encoding.chars.length))
+        return false;
+
+      for (unsigned idx = 0; idx < encoding.chars.length; idx++)
+      {
+        uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]);
+        combined_chars.push (v);
+      }
+
+      delta_row_encoding_t combined_encoding_obj (std::move (combined_chars));
+      for (const auto& row : hb_concat (encoding.items, other_encoding.items))
+        combined_encoding_obj.add_row (row);
+
+      for (unsigned idx = 0; idx < encoding_objs.length; idx++)
+      {
+        if (removed_todo_idxes.has (idx)) continue;
+
+        const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx];
+        if (obj.chars == combined_chars)
+        {
+          for (const auto& row : obj.items)
+            combined_encoding_obj.add_row (row);
+
+          removed_todo_idxes.add (idx);
+          continue;
+        }
+
+        int combined_gain = combined_encoding_obj.gain_from_merging (obj);
+        if (combined_gain > 0)
+          queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0);
+      }
+
+      encoding_objs.push (std::move (combined_encoding_obj));
+    }
+
+    int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population ();
+    if (num_final_encodings <= 0) return false;
+
+    if (!encodings.alloc (num_final_encodings)) return false;
+    for (unsigned i = 0; i < encoding_objs.length; i++)
+    {
+      if (removed_todo_idxes.has (i)) continue;
+      encodings.push (std::move (encoding_objs.arrayZ[i]));
+    }
+
+    /* sort again based on width, make result deterministic */
+    encodings.qsort (delta_row_encoding_t::cmp_width);
+
+    return compile_varidx_map (front_mapping);
+  }
+
+  private:
+  /* compile varidx_map for one VarData subtable (index specified by major) */
+  bool compile_varidx_map (const hb_hashmap_t*>& front_mapping)
+  {
+    /* full encoding_row -> new VarIdxes mapping */
+    hb_hashmap_t*, unsigned> back_mapping;
+
+    for (unsigned major = 0; major < encodings.length; major++)
+    {
+      delta_row_encoding_t& encoding = encodings[major];
+      /* just sanity check, this shouldn't happen */
+      if (encoding.is_empty ())
+        return false;
+
+      unsigned num_rows = encoding.items.length;
+
+      /* sort rows, make result deterministic */
+      encoding.items.qsort (_cmp_row);
+
+      /* compile old to new var_idxes mapping */
+      for (unsigned minor = 0; minor < num_rows; minor++)
+      {
+        unsigned new_varidx = (major << 16) + minor;
+        back_mapping.set (encoding.items.arrayZ[minor], new_varidx);
+      }
+    }
+
+    for (auto _ : front_mapping.iter ())
+    {
+      unsigned old_varidx = _.first;
+      unsigned *new_varidx;
+      if (back_mapping.has (_.second, &new_varidx))
+        varidx_map.set (old_varidx, *new_varidx);
+      else
+        varidx_map.set (old_varidx, HB_OT_LAYOUT_NO_VARIATIONS_INDEX);
+    }
+    return !varidx_map.in_error ();
+  }
+
+  static int _cmp_row (const void *pa, const void *pb)
+  {
+    /* compare pointers of vectors(const hb_vector_t*) that represent a row */
+    const hb_vector_t** a = (const hb_vector_t**) pa;
+    const hb_vector_t** b = (const hb_vector_t**) pb;
+
+    for (unsigned i = 0; i < (*b)->length; i++)
+    {
+      int va = (*a)->arrayZ[i];
+      int vb = (*b)->arrayZ[i];
+      if (va != vb)
+        return va < vb ? -1 : 1;
+    }
+    return 0;
+  }
+};
+
 } /* namespace OT */
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -27,6 +27,7 @@
 #define HB_OT_VAR_CVAR_TABLE_HH
 
 #include "hb-ot-var-common.hh"
+#include "hb-ot-var-fvar-table.hh"
 
 
 namespace OT {
@@ -51,6 +52,27 @@
   const TupleVariationData* get_tuple_var_data (void) const
   { return &tupleVariationData; }
 
+  bool decompile_tuple_variations (unsigned axis_count,
+                                   unsigned point_count,
+                                   hb_blob_t *blob,
+                                   bool is_gvar,
+                                   const hb_map_t *axes_old_index_tag_map,
+                                   TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const
+  {
+    hb_vector_t shared_indices;
+    TupleVariationData::tuple_iterator_t iterator;
+    hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4);
+    if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this,
+                                                 shared_indices, &iterator))
+      return false;
+
+    return tupleVariationData.decompile_tuple_variations (point_count, is_gvar, iterator,
+                                                          axes_old_index_tag_map,
+                                                          shared_indices,
+                                                          hb_array (),
+                                                          tuple_variations);
+  }
+
   static bool calculate_cvt_deltas (unsigned axis_count,
                                     hb_array_t coords,
                                     unsigned num_cvt_item,
@@ -105,6 +127,46 @@
     return true;
   }
 
+  bool serialize (hb_serialize_context_t *c,
+                  TupleVariationData::tuple_variations_t& tuple_variations) const
+  {
+    TRACE_SERIALIZE (this);
+    if (!tuple_variations) return_trace (false);
+    if (unlikely (!c->embed (version))) return_trace (false);
+
+    return_trace (tupleVariationData.serialize (c, false, tuple_variations));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    OT::TupleVariationData::tuple_variations_t tuple_variations;
+    unsigned axis_count = c->plan->axes_old_index_tag_map.get_population ();
+
+    const hb_tag_t cvt = HB_TAG('c','v','t',' ');
+    hb_blob_t *cvt_blob = hb_face_reference_table (c->plan->source, cvt);
+    unsigned point_count = hb_blob_get_length (cvt_blob) / FWORD::static_size;
+    hb_blob_destroy (cvt_blob);
+
+    if (!decompile_tuple_variations (axis_count, point_count,
+                                     c->source_blob, false,
+                                     &(c->plan->axes_old_index_tag_map),
+                                     tuple_variations))
+      return_trace (false);
+
+    if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances))
+      return_trace (false);
+
+    if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map,
+                                         false /* do not use shared points */))
+      return_trace (false);
+
+    return_trace (serialize (c->serializer, tuple_variations));
+  }
+
   static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan,
                                         const TupleVariationData *tuple_var_data,
                                         const void *base)
@@ -126,7 +188,6 @@
       hb_blob_destroy (cvt_prime_blob);
       return false;
     }
-    hb_memset (cvt_deltas.arrayZ, 0, cvt_deltas.get_size ());
 
     if (!calculate_cvt_deltas (plan->normalized_coords.length, plan->normalized_coords.as_array (),
                                num_cvt_item, tuple_var_data, base, cvt_deltas))
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -39,6 +39,24 @@
 
 namespace OT {
 
+static bool axis_coord_pinned_or_within_axis_range (const hb_array_t coords,
+                                                    unsigned axis_index,
+                                                    Triple axis_limit)
+{
+  float axis_coord = coords[axis_index].to_float ();
+  if (axis_limit.is_point ())
+  {
+    if (axis_limit.minimum != axis_coord)
+      return false;
+  }
+  else
+  {
+    if (axis_coord < axis_limit.minimum ||
+        axis_coord > axis_limit.maximum)
+      return false;
+  }
+  return true;
+}
 
 struct InstanceRecord
 {
@@ -47,6 +65,27 @@
   hb_array_t get_coordinates (unsigned int axis_count) const
   { return coordinatesZ.as_array (axis_count); }
 
+  bool keep_instance (unsigned axis_count,
+                      const hb_map_t *axes_index_tag_map,
+                      const hb_hashmap_t *axes_location) const
+  {
+    if (axes_location->is_empty ()) return true;
+    const hb_array_t coords = get_coordinates (axis_count);
+    for (unsigned i = 0 ; i < axis_count; i++)
+    {
+      uint32_t *axis_tag;
+      if (!axes_index_tag_map->has (i, &axis_tag))
+        return false;
+      if (!axes_location->has (*axis_tag))
+        continue;
+
+      Triple axis_limit = axes_location->get (*axis_tag);
+      if (!axis_coord_pinned_or_within_axis_range (coords, i, axis_limit))
+        return false;
+    }
+    return true;
+  }
+
   bool subset (hb_subset_context_t *c,
                unsigned axis_count,
                bool has_postscript_nameid) const
@@ -56,19 +95,22 @@
     if (unlikely (!c->serializer->embed (flags))) return_trace (false);
 
     const hb_array_t coords = get_coordinates (axis_count);
-    const hb_hashmap_t *axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t *axes_location = &c->plan->user_axes_location;
     for (unsigned i = 0 ; i < axis_count; i++)
     {
       uint32_t *axis_tag;
+      Triple *axis_limit;
       // only keep instances whose coordinates == pinned axis location
-      if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) continue;
-
-      if (axes_location->has (*axis_tag) &&
-          fabsf (axes_location->get (*axis_tag) - coords[i].to_float ()) > 0.001f)
-        return_trace (false);
+      if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) return_trace (false);
+      if (axes_location->has (*axis_tag, &axis_limit))
+      {
+        if (!axis_coord_pinned_or_within_axis_range (coords, i, *axis_limit))
+          return_trace (false);
 
-      if (!c->plan->axes_index_map.has (i))
-        continue;
+        //skip pinned axis
+        if (axis_limit->is_point ())
+          continue;
+      }
 
       if (!c->serializer->embed (coords[i]))
         return_trace (false);
@@ -186,6 +228,30 @@
     return defaultValue.to_float ();
   }
 
+  TripleDistances get_triple_distances () const
+  {
+    float min, default_, max;
+    get_coordinates (min, default_, max);
+    return TripleDistances (min, default_, max);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    const hb_hashmap_t& user_axes_location = c->plan->user_axes_location;
+    Triple *axis_limit;
+    if (user_axes_location.has (axisTag, &axis_limit))
+    {
+      out->minValue.set_float (axis_limit->minimum);
+      out->defaultValue.set_float (axis_limit->middle);
+      out->maxValue.set_float (axis_limit->maximum);
+    }
+    return_trace (true);
+  }
+
   public:
   Tag           axisTag;        /* Tag identifying the design variation for the axis. */
   protected:
@@ -216,7 +282,8 @@
                   axisSize == 20 && /* Assumed in our code. */
                   instanceSize >= axisCount * 4 + 4 &&
                   get_axes ().sanitize (c) &&
-                  c->check_range (get_instance (0), instanceCount, instanceSize));
+                  c->check_range (&StructAfter (get_axes ()),
+                                  instanceCount, instanceSize));
   }
 
   unsigned int get_axis_count () const { return axisCount; }
@@ -314,21 +381,19 @@
     return axisCount;
   }
 
-  void collect_name_ids (hb_hashmap_t *user_axes_location,
+  void collect_name_ids (hb_hashmap_t *user_axes_location,
+                         hb_map_t *axes_old_index_tag_map,
                          hb_set_t *nameids  /* IN/OUT */) const
   {
     if (!has_data ()) return;
-    hb_map_t pinned_axes;
 
     auto axis_records = get_axes ();
     for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
     {
       hb_tag_t axis_tag = axis_records[i].get_axis_tag ();
-      if (user_axes_location->has (axis_tag))
-      {
-        pinned_axes.set (i, axis_tag);
+      if (user_axes_location->has (axis_tag) &&
+          user_axes_location->get (axis_tag).is_point ())
         continue;
-      }
 
       nameids->add (axis_records[i].get_name_id ());
     }
@@ -337,16 +402,7 @@
     {
       const InstanceRecord *instance = get_instance (i);
 
-      if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount))
-                  | hb_filter (pinned_axes, hb_first)
-                  | hb_map ([&] (const hb_pair_t& _)
-                            {
-                              hb_tag_t axis_tag = pinned_axes.get (_.first);
-                              float location = user_axes_location->get (axis_tag);
-                              if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true;
-                              return false;
-                            })
-                  ))
+      if (!instance->keep_instance (axisCount, axes_old_index_tag_map, user_axes_location))
         continue;
 
       nameids->add (instance->subfamilyNameID);
@@ -384,21 +440,25 @@
     for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
     {
       if (!c->plan->axes_index_map.has (i)) continue;
-      if (unlikely (!c->serializer->embed (axes_records[i])))
+      if (unlikely (!axes_records[i].subset (c)))
         return_trace (false);
     }
 
     if (!c->serializer->check_assign (out->firstAxis, get_size (), HB_SERIALIZE_ERROR_INT_OVERFLOW))
       return_trace (false);
 
+    unsigned num_retained_instances = 0;
     for (unsigned i = 0 ; i < (unsigned)instanceCount; i++)
     {
       const InstanceRecord *instance = get_instance (i);
       auto snap = c->serializer->snapshot ();
       if (!instance->subset (c, axisCount, has_postscript_nameid))
         c->serializer->revert (snap);
+      else
+        num_retained_instances++;
     }
-    return_trace (true);
+
+    return_trace (c->serializer->check_assign (out->instanceCount, num_retained_instances, HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   public:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -39,60 +39,255 @@
 
 namespace OT {
 
-struct contour_point_t
+struct GlyphVariationData : TupleVariationData
+{};
+
+struct glyph_variations_t
 {
-  void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
-  { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
+  using tuple_variations_t = TupleVariationData::tuple_variations_t;
+  hb_vector_t glyph_variations;
 
-  void translate (const contour_point_t &p) { x += p.x; y += p.y; }
+  hb_vector_t compiled_shared_tuples;
+  private:
+  unsigned shared_tuples_count = 0;
 
-  float x = 0.f;
-  float y = 0.f;
-  uint8_t flag = 0;
-  bool is_end_point = false;
-};
+  /* shared coords-> index map after instantiation */
+  hb_hashmap_t*, unsigned> shared_tuples_idx_map;
 
-struct contour_point_vector_t : hb_vector_t
-{
-  void extend (const hb_array_t &a)
+  public:
+  unsigned compiled_shared_tuples_count () const
+  { return shared_tuples_count; }
+
+  unsigned compiled_byte_size () const
   {
-    unsigned int old_len = length;
-    if (unlikely (!resize (old_len + a.length, false)))
-      return;
-    auto arrayZ = this->arrayZ + old_len;
-    unsigned count = a.length;
-    hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
-  }
-
-  void transform (const float (&matrix)[4])
-  {
-    if (matrix[0] == 1.f && matrix[1] == 0.f &&
-        matrix[2] == 0.f && matrix[3] == 1.f)
-      return;
-    auto arrayZ = this->arrayZ;
-    unsigned count = length;
-    for (unsigned i = 0; i < count; i++)
+    unsigned byte_size = 0;
+    for (const auto& _ : glyph_variations)
+      byte_size += _.get_compiled_byte_size ();
+
+    return byte_size;
+  }
+
+  bool create_from_glyphs_var_data (unsigned axis_count,
+                                    const hb_array_t shared_tuples,
+                                    const hb_subset_plan_t *plan,
+                                    const hb_hashmap_t& new_gid_var_data_map)
+  {
+    if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true)))
+      return false;
+
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    for (auto &_ : it)
     {
-      contour_point_t &p = arrayZ[i];
-      float x_ = p.x * matrix[0] + p.y * matrix[2];
-           p.y = p.x * matrix[1] + p.y * matrix[3];
-      p.x = x_;
+      hb_codepoint_t new_gid = _.first;
+      contour_point_vector_t *all_contour_points;
+      if (!new_gid_var_data_map.has (new_gid) ||
+          !plan->new_gid_contour_points_map.has (new_gid, &all_contour_points))
+        return false;
+      hb_bytes_t var_data = new_gid_var_data_map.get (new_gid);
+
+      const GlyphVariationData* p = reinterpret_cast (var_data.arrayZ);
+      hb_vector_t shared_indices;
+      GlyphVariationData::tuple_iterator_t iterator;
+      tuple_variations_t tuple_vars;
+
+      /* in case variation data is empty, push an empty struct into the vector,
+       * keep the vector in sync with the new_to_old_gid_list */
+      if (!var_data || ! p->has_data () || !all_contour_points->length ||
+          !GlyphVariationData::get_tuple_iterator (var_data, axis_count,
+                                                   var_data.arrayZ,
+                                                   shared_indices, &iterator))
+      {
+        glyph_variations.push (std::move (tuple_vars));
+        continue;
+      }
+
+      if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */,
+                                          iterator, &(plan->axes_old_index_tag_map),
+                                          shared_indices, shared_tuples,
+                                          tuple_vars /* OUT */))
+        return false;
+      glyph_variations.push (std::move (tuple_vars));
     }
+    return !glyph_variations.in_error () && glyph_variations.length == plan->new_to_old_gid_list.length;
   }
 
-  void translate (const contour_point_t& delta)
+  bool instantiate (const hb_subset_plan_t *plan)
   {
-    if (delta.x == 0.f && delta.y == 0.f)
-      return;
-    auto arrayZ = this->arrayZ;
-    unsigned count = length;
+    unsigned count = plan->new_to_old_gid_list.length;
     for (unsigned i = 0; i < count; i++)
-      arrayZ[i].translate (delta);
+    {
+      hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first;
+      contour_point_vector_t *all_points;
+      if (!plan->new_gid_contour_points_map.has (new_gid, &all_points))
+        return false;
+      if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points))
+        return false;
+    }
+    return true;
   }
-};
 
-struct GlyphVariationData : TupleVariationData
-{};
+  bool compile_bytes (const hb_map_t& axes_index_map,
+                      const hb_map_t& axes_old_index_tag_map)
+  {
+    if (!compile_shared_tuples (axes_index_map, axes_old_index_tag_map))
+      return false;
+    for (tuple_variations_t& vars: glyph_variations)
+      if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map,
+                               true, /* use shared points*/
+                               &shared_tuples_idx_map))
+        return false;
+
+    return true;
+  }
+
+  bool compile_shared_tuples (const hb_map_t& axes_index_map,
+                              const hb_map_t& axes_old_index_tag_map)
+  {
+    /* key is pointer to compiled_peak_coords inside each tuple, hashing
+     * function will always deref pointers first */
+    hb_hashmap_t*, unsigned> coords_count_map;
+
+    /* count the num of shared coords */
+    for (tuple_variations_t& vars: glyph_variations)
+    {
+      for (tuple_delta_t& var : vars.tuple_vars)
+      {
+        if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map))
+          return false;
+        unsigned* count;
+        if (coords_count_map.has (&(var.compiled_peak_coords), &count))
+          coords_count_map.set (&(var.compiled_peak_coords), *count + 1);
+        else
+          coords_count_map.set (&(var.compiled_peak_coords), 1);
+      }
+    }
+
+    if (!coords_count_map || coords_count_map.in_error ())
+      return false;
+
+    /* add only those coords that are used more than once into the vector and sort */
+    hb_vector_t*> shared_coords;
+    if (unlikely (!shared_coords.alloc (coords_count_map.get_population ())))
+      return false;
+
+    for (const auto _ : coords_count_map.iter ())
+    {
+      if (_.second == 1) continue;
+      shared_coords.push (_.first);
+    }
+
+    /* no shared tuples: no coords are used more than once */
+    if (!shared_coords) return true;
+    /* sorting based on the coords frequency first (high to low), then compare
+     * the coords bytes */
+    hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t*), _cmp_coords, (void *) (&coords_count_map));
+
+    /* build shared_coords->idx map and shared tuples byte array */
+
+    shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length);
+    unsigned len = shared_tuples_count * (shared_coords[0]->length);
+    if (unlikely (!compiled_shared_tuples.alloc (len)))
+      return false;
+
+    for (unsigned i = 0; i < shared_tuples_count; i++)
+    {
+      shared_tuples_idx_map.set (shared_coords[i], i);
+      /* add a concat() in hb_vector_t? */
+      for (char c : shared_coords[i]->iter ())
+        compiled_shared_tuples.push (c);
+    }
+
+    return true;
+  }
+
+  static int _cmp_coords (const void *pa, const void *pb, void *arg)
+  {
+    const hb_hashmap_t*, unsigned>* coords_count_map =
+        reinterpret_cast*, unsigned>*> (arg);
+
+    /* shared_coords is hb_vector_t*> so casting pa/pb
+     * to be a pointer to a pointer */
+    const hb_vector_t** a = reinterpret_cast**> (const_cast(pa));
+    const hb_vector_t** b = reinterpret_cast**> (const_cast(pb));
+
+    bool has_a = coords_count_map->has (*a);
+    bool has_b = coords_count_map->has (*b);
+
+    if (has_a && has_b)
+    {
+      unsigned a_num = coords_count_map->get (*a);
+      unsigned b_num = coords_count_map->get (*b);
+
+      if (a_num != b_num)
+        return b_num - a_num;
+
+      return (*b)->as_array().cmp ((*a)->as_array ());
+    }
+    else if (has_a) return -1;
+    else if (has_b) return 1;
+    else return 0;
+  }
+
+  template
+  bool serialize_glyph_var_data (hb_serialize_context_t *c,
+                                 Iterator it,
+                                 bool long_offset,
+                                 unsigned num_glyphs,
+                                 char* glyph_var_data_offsets /* OUT: glyph var data offsets array */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    if (long_offset)
+    {
+      ((HBUINT32 *) glyph_var_data_offsets)[0] = 0;
+      glyph_var_data_offsets += 4;
+    }
+    else
+    {
+      ((HBUINT16 *) glyph_var_data_offsets)[0] = 0;
+      glyph_var_data_offsets += 2;
+    }
+    unsigned glyph_offset = 0;
+    hb_codepoint_t last_gid = 0;
+    unsigned idx = 0;
+
+    TupleVariationData* cur_glyph = c->start_embed ();
+    if (!cur_glyph) return_trace (false);
+    for (auto &_ : it)
+    {
+      hb_codepoint_t gid = _.first;
+      if (long_offset)
+        for (; last_gid < gid; last_gid++)
+          ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset;
+      else
+        for (; last_gid < gid; last_gid++)
+          ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2;
+
+      if (idx >= glyph_variations.length) return_trace (false);
+      if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false);
+      TupleVariationData* next_glyph = c->start_embed ();
+      glyph_offset += (char *) next_glyph - (char *) cur_glyph;
+
+      if (long_offset)
+        ((HBUINT32 *) glyph_var_data_offsets)[gid] = glyph_offset;
+      else
+        ((HBUINT16 *) glyph_var_data_offsets)[gid] = glyph_offset / 2;
+
+      last_gid++;
+      idx++;
+      cur_glyph = next_glyph;
+    }
+
+    if (long_offset)
+      for (; last_gid < num_glyphs; last_gid++)
+        ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset;
+    else
+      for (; last_gid < num_glyphs; last_gid++)
+        ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2;
+    return_trace (true);
+  }
+};
 
 struct gvar
 {
@@ -112,9 +307,101 @@
   bool sanitize (hb_sanitize_context_t *c) const
   { return sanitize_shallow (c); }
 
+  bool decompile_glyph_variations (hb_subset_context_t *c,
+                                   glyph_variations_t& glyph_vars /* OUT */) const
+  {
+    hb_hashmap_t new_gid_var_data_map;
+    auto it = hb_iter (c->plan->new_to_old_gid_list);
+    if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+    {
+      new_gid_var_data_map.set (0, hb_bytes_t ());
+      it++;
+    }
+
+    for (auto &_ : it)
+    {
+      hb_codepoint_t new_gid = _.first;
+      hb_codepoint_t old_gid = _.second;
+      hb_bytes_t var_data_bytes = get_glyph_var_data_bytes (c->source_blob, glyphCountX, old_gid);
+      new_gid_var_data_map.set (new_gid, var_data_bytes);
+    }
+
+    if (new_gid_var_data_map.in_error ()) return false;
+
+    hb_array_t shared_tuples = (this+sharedTuples).as_array ((unsigned) sharedTupleCount * (unsigned) axisCount);
+    return glyph_vars.create_from_glyphs_var_data (axisCount, shared_tuples, c->plan, new_gid_var_data_map);
+  }
+
+  template
+  bool serialize (hb_serialize_context_t *c,
+                  const glyph_variations_t& glyph_vars,
+                  Iterator it,
+                  unsigned axis_count,
+                  unsigned num_glyphs) const
+  {
+    TRACE_SERIALIZE (this);
+    gvar *out = c->allocate_min ();
+    if (unlikely (!out)) return_trace (false);
+
+    out->version.major = 1;
+    out->version.minor = 0;
+    out->axisCount = axis_count;
+    out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
+
+    unsigned glyph_var_data_size = glyph_vars.compiled_byte_size ();
+    bool long_offset = glyph_var_data_size & ~0xFFFFu;
+    out->flags = long_offset ? 1 : 0;
+
+    HBUINT8 *glyph_var_data_offsets = c->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false);
+    if (!glyph_var_data_offsets) return_trace (false);
+
+    /* shared tuples */
+    unsigned shared_tuple_count = glyph_vars.compiled_shared_tuples_count ();
+    out->sharedTupleCount = shared_tuple_count;
+
+    if (!shared_tuple_count)
+      out->sharedTuples = 0;
+    else
+    {
+      hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c);
+      if (!shared_tuples.arrayZ) return_trace (false);
+      out->sharedTuples = shared_tuples.arrayZ - (char *) out;
+    }
+
+    char *glyph_var_data = c->start_embed ();
+    if (!glyph_var_data) return_trace (false);
+    out->dataZ = glyph_var_data - (char *) out;
+
+    return_trace (glyph_vars.serialize_glyph_var_data (c, it, long_offset, num_glyphs,
+                                                       (char *) glyph_var_data_offsets));
+  }
+
+  bool instantiate (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    glyph_variations_t glyph_vars;
+    if (!decompile_glyph_variations (c, glyph_vars))
+      return_trace (false);
+
+    if (!glyph_vars.instantiate (c->plan)) return_trace (false);
+    if (!glyph_vars.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map))
+      return_trace (false);
+
+    unsigned axis_count = c->plan->axes_index_map.get_population ();
+    unsigned num_glyphs = c->plan->num_output_glyphs ();
+    auto it = hb_iter (c->plan->new_to_old_gid_list);
+    return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs));
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    if (c->plan->normalized_coords)
+      return_trace (instantiate (c));
 
     unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0;
 
@@ -129,20 +416,20 @@
     unsigned int num_glyphs = c->plan->num_output_glyphs ();
     out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
 
+    auto it = hb_iter (c->plan->new_to_old_gid_list);
+    if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+      it++;
     unsigned int subset_data_size = 0;
-    for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
-         gid < num_glyphs;
-         gid++)
+    for (auto &_ : it)
     {
-      hb_codepoint_t old_gid;
-      if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
+      hb_codepoint_t old_gid = _.second;
       subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length;
     }
 
     bool long_offset = subset_data_size & ~0xFFFFu;
     out->flags = long_offset ? 1 : 0;
 
-    HBUINT8 *subset_offsets = c->serializer->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1));
+    HBUINT8 *subset_offsets = c->serializer->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false);
     if (!subset_offsets) return_trace (false);
 
     /* shared tuples */
@@ -157,36 +444,61 @@
       hb_memcpy (tuples, this+sharedTuples, shared_tuple_size);
     }
 
-    char *subset_data = c->serializer->allocate_size (subset_data_size);
+    char *subset_data = c->serializer->allocate_size (subset_data_size, false);
     if (!subset_data) return_trace (false);
     out->dataZ = subset_data - (char *) out;
 
+
+    if (long_offset)
+    {
+      ((HBUINT32 *) subset_offsets)[0] = 0;
+      subset_offsets += 4;
+    }
+    else
+    {
+      ((HBUINT16 *) subset_offsets)[0] = 0;
+      subset_offsets += 2;
+    }
     unsigned int glyph_offset = 0;
-    for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
-         gid < num_glyphs;
-         gid++)
-    {
-      hb_codepoint_t old_gid;
-      hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid)
-                                ? get_glyph_var_data_bytes (c->source_blob,
+
+    hb_codepoint_t last = 0;
+    it = hb_iter (c->plan->new_to_old_gid_list);
+    if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+      it++;
+    for (auto &_ : it)
+    {
+      hb_codepoint_t gid = _.first;
+      hb_codepoint_t old_gid = _.second;
+
+      if (long_offset)
+        for (; last < gid; last++)
+          ((HBUINT32 *) subset_offsets)[last] = glyph_offset;
+      else
+        for (; last < gid; last++)
+          ((HBUINT16 *) subset_offsets)[last] = glyph_offset / 2;
+
+      hb_bytes_t var_data_bytes = get_glyph_var_data_bytes (c->source_blob,
                                                             glyph_count,
-                                                            old_gid)
-                                : hb_bytes_t ();
+                                                            old_gid);
+
+      hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
+      subset_data += var_data_bytes.length;
+      glyph_offset += var_data_bytes.length;
 
       if (long_offset)
         ((HBUINT32 *) subset_offsets)[gid] = glyph_offset;
       else
         ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
 
-      if (var_data_bytes.length > 0)
-        hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
-      subset_data += var_data_bytes.length;
-      glyph_offset += var_data_bytes.length;
+      last++; // Skip over gid
     }
+
     if (long_offset)
-      ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset;
+      for (; last < num_glyphs; last++)
+        ((HBUINT32 *) subset_offsets)[last] = glyph_offset;
     else
-      ((HBUINT16 *) subset_offsets)[num_glyphs] = glyph_offset / 2;
+      for (; last < num_glyphs; last++)
+        ((HBUINT16 *) subset_offsets)[last] = glyph_offset / 2;
 
     return_trace (true);
   }
@@ -235,21 +547,24 @@
       for (unsigned i = 0; i < count; i++)
       {
         hb_array_t tuple = shared_tuples.sub_array (axis_count * i, axis_count);
-        int idx = -1;
+        int idx1 = -1, idx2 = -1;
         for (unsigned j = 0; j < axis_count; j++)
         {
-          F2DOT14 peak = tuple.arrayZ[j];
+          const F2DOT14 &peak = tuple.arrayZ[j];
           if (peak.to_int () != 0)
           {
-            if (idx != -1)
+            if (idx1 == -1)
+              idx1 = j;
+            else if (idx2 == -1)
+              idx2 = j;
+            else
             {
-              idx = -1;
+              idx1 = idx2 = -1;
               break;
             }
-            idx = j;
           }
         }
-        shared_tuple_active_idx[i] = idx;
+        shared_tuple_active_idx.arrayZ[i] = {idx1, idx2};
       }
     }
     ~accelerator_t () { table.destroy (); }
@@ -285,10 +600,9 @@
     public:
     bool apply_deltas_to_points (hb_codepoint_t glyph,
                                  hb_array_t coords,
-                                 const hb_array_t points) const
+                                 const hb_array_t points,
+                                 bool phantom_only = false) const
     {
-      if (!coords) return true;
-
       if (unlikely (glyph >= glyphCount)) return true;
 
       hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph);
@@ -311,16 +625,17 @@
       hb_vector_t end_points; // Populated lazily
 
       unsigned num_coords = table->axisCount;
-      hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
+      hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * num_coords);
 
       hb_vector_t private_indices;
       hb_vector_t x_deltas;
       hb_vector_t y_deltas;
+      unsigned count = points.length;
       bool flush = false;
       do
       {
         float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples,
-                                                                 shared_tuple_active_idx.in_error () ? nullptr : &shared_tuple_active_idx);
+                                                                 &shared_tuple_active_idx);
         if (scalar == 0.f) continue;
         const HBUINT8 *p = iterator.get_serialized_data ();
         unsigned int length = iterator.current_tuple->get_data_size ();
@@ -329,8 +644,10 @@
 
         if (!deltas)
         {
-          if (unlikely (!deltas_vec.resize (points.length))) return false;
+          if (unlikely (!deltas_vec.resize (count, false))) return false;
           deltas = deltas_vec.as_array ();
+          hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0,
+                     (phantom_only ? 4 : count) * sizeof (deltas[0]));
         }
 
         const HBUINT8 *end = p + length;
@@ -350,7 +667,7 @@
 
         if (!apply_to_all)
         {
-          if (!orig_points)
+          if (!orig_points && !phantom_only)
           {
             orig_points_vec.extend (points);
             if (unlikely (orig_points_vec.in_error ())) return false;
@@ -359,15 +676,17 @@
 
           if (flush)
           {
-            for (unsigned int i = 0; i < points.length; i++)
+            for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
               points.arrayZ[i].translate (deltas.arrayZ[i]);
             flush = false;
 
           }
-          hb_memset (deltas.arrayZ, 0, deltas.get_size ());
+          hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0,
+                     (phantom_only ? 4 : count) * sizeof (deltas[0]));
         }
 
-        if (scalar != 1.0f)
+        if (HB_OPTIMIZE_SIZE_VAL)
+        {
           for (unsigned int i = 0; i < num_deltas; i++)
           {
             unsigned int pt_index;
@@ -378,34 +697,68 @@
               pt_index = indices[i];
               if (unlikely (pt_index >= deltas.length)) continue;
             }
+            if (phantom_only && pt_index < count - 4) continue;
             auto &delta = deltas.arrayZ[pt_index];
             delta.flag = 1;     /* this point is referenced, i.e., explicit deltas specified */
             delta.x += x_deltas.arrayZ[i] * scalar;
             delta.y += y_deltas.arrayZ[i] * scalar;
           }
+        }
         else
-          for (unsigned int i = 0; i < num_deltas; i++)
+        {
+          /* Ouch. Four cases... for optimization. */
+          if (scalar != 1.0f)
           {
-            unsigned int pt_index;
             if (apply_to_all)
-              pt_index = i;
+              for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
+              {
+                unsigned int pt_index = i;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.x += x_deltas.arrayZ[i] * scalar;
+                delta.y += y_deltas.arrayZ[i] * scalar;
+              }
             else
-            {
-              pt_index = indices[i];
-              if (unlikely (pt_index >= deltas.length)) continue;
-            }
-            auto &delta = deltas.arrayZ[pt_index];
-            delta.flag = 1;     /* this point is referenced, i.e., explicit deltas specified */
-            delta.x += x_deltas.arrayZ[i];
-            delta.y += y_deltas.arrayZ[i];
+              for (unsigned int i = 0; i < num_deltas; i++)
+              {
+                unsigned int pt_index = indices[i];
+                if (unlikely (pt_index >= deltas.length)) continue;
+                if (phantom_only && pt_index < count - 4) continue;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+                delta.x += x_deltas.arrayZ[i] * scalar;
+                delta.y += y_deltas.arrayZ[i] * scalar;
+              }
+          }
+          else
+          {
+            if (apply_to_all)
+              for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
+              {
+                unsigned int pt_index = i;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.x += x_deltas.arrayZ[i];
+                delta.y += y_deltas.arrayZ[i];
+              }
+            else
+              for (unsigned int i = 0; i < num_deltas; i++)
+              {
+                unsigned int pt_index = indices[i];
+                if (unlikely (pt_index >= deltas.length)) continue;
+                if (phantom_only && pt_index < count - 4) continue;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+                delta.x += x_deltas.arrayZ[i];
+                delta.y += y_deltas.arrayZ[i];
+              }
           }
+        }
 
         /* infer deltas for unreferenced points */
-        if (!apply_to_all)
+        if (!apply_to_all && !phantom_only)
         {
           if (!end_points)
           {
-            for (unsigned i = 0; i < points.length; ++i)
+            for (unsigned i = 0; i < count; ++i)
               if (points.arrayZ[i].is_end_point)
                 end_points.push (i);
             if (unlikely (end_points.in_error ())) return false;
@@ -465,8 +818,10 @@
       } while (iterator.move_to_next ());
 
       if (flush)
-        for (unsigned int i = 0; i < points.length; i++)
+      {
+        for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
           points.arrayZ[i].translate (deltas.arrayZ[i]);
+      }
 
       return true;
     }
@@ -476,7 +831,7 @@
     private:
     hb_blob_ptr_t table;
     unsigned glyphCount;
-    hb_vector_t shared_tuple_active_idx;
+    hb_vector_t> shared_tuple_active_idx;
   };
 
   protected:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -45,7 +45,8 @@
   void init (const DeltaSetIndexMap  &index_map,
              hb_inc_bimap_t          &outer_map,
              hb_vector_t &inner_sets,
-             const hb_subset_plan_t  *plan)
+             const hb_subset_plan_t  *plan,
+             bool bypass_empty = true)
   {
     map_count = 0;
     outer_bit_count = 0;
@@ -53,55 +54,51 @@
     max_inners.init ();
     output_map.init ();
 
-    if (&index_map == &Null (DeltaSetIndexMap)) return;
+    if (bypass_empty && !index_map.get_map_count ()) return;
 
     unsigned int        last_val = (unsigned int)-1;
-    hb_codepoint_t      last_gid = (hb_codepoint_t)-1;
-    hb_codepoint_t      gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ());
+    hb_codepoint_t      last_gid = HB_CODEPOINT_INVALID;
 
     outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count ();
     max_inners.resize (inner_sets.length);
     for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0;
 
     /* Search backwards for a map value different from the last map value */
-    for (; gid > 0; gid--)
+    auto &new_to_old_gid_list = plan->new_to_old_gid_list;
+    unsigned count = new_to_old_gid_list.length;
+    for (unsigned j = count; j; j--)
     {
-      hb_codepoint_t    old_gid;
-      if (!plan->old_gid_for_new_gid (gid - 1, &old_gid))
-      {
-        if (last_gid == (hb_codepoint_t) -1)
-          continue;
-        else
-          break;
-      }
+      hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first;
+      hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second;
 
       unsigned int v = index_map.map (old_gid);
-      if (last_gid == (hb_codepoint_t) -1)
+      if (last_gid == HB_CODEPOINT_INVALID)
       {
         last_val = v;
         last_gid = gid;
         continue;
       }
-      if (v != last_val) break;
+      if (v != last_val)
+        break;
 
       last_gid = gid;
     }
 
     if (unlikely (last_gid == (hb_codepoint_t)-1)) return;
-    map_count = last_gid;
-    for (gid = 0; gid < map_count; gid++)
+    map_count = last_gid + 1;
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t    old_gid;
-      if (plan->old_gid_for_new_gid (gid, &old_gid))
-      {
-        unsigned int v = index_map.map (old_gid);
-        unsigned int outer = v >> 16;
-        unsigned int inner = v & 0xFFFF;
-        outer_map.add (outer);
-        if (inner > max_inners[outer]) max_inners[outer] = inner;
-        if (outer >= inner_sets.length) return;
-        inner_sets[outer]->add (inner);
-      }
+      hb_codepoint_t gid = _.first;
+      if (gid >= map_count) break;
+
+      hb_codepoint_t old_gid = _.second;
+      unsigned int v = index_map.map (old_gid);
+      unsigned int outer = v >> 16;
+      unsigned int inner = v & 0xFFFF;
+      outer_map.add (outer);
+      if (inner > max_inners[outer]) max_inners[outer] = inner;
+      if (outer >= inner_sets.length) return;
+      inner_sets[outer]->add (inner);
     }
   }
 
@@ -116,8 +113,6 @@
               const hb_vector_t &inner_maps,
               const hb_subset_plan_t *plan)
   {
-    if (input_map == &Null (DeltaSetIndexMap)) return;
-
     for (unsigned int i = 0; i < max_inners.length; i++)
     {
       if (inner_maps[i].get_population () == 0) continue;
@@ -125,19 +120,48 @@
       if (bit_count > inner_bit_count) inner_bit_count = bit_count;
     }
 
-    output_map.resize (map_count);
-    for (hb_codepoint_t gid = 0; gid < output_map.length; gid++)
+    if (unlikely (!output_map.resize (map_count))) return;
+    for (const auto &_ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t    old_gid;
-      if (plan->old_gid_for_new_gid (gid, &old_gid))
-      {
-        uint32_t v = input_map->map (old_gid);
-        unsigned int outer = v >> 16;
-        output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
-      }
-      else
-        output_map[gid] = 0;    /* Map unused glyph to outer/inner=0/0 */
+      hb_codepoint_t new_gid = _.first;
+      hb_codepoint_t old_gid = _.second;
+
+      if (unlikely (new_gid >= map_count)) break;
+
+      uint32_t v = input_map->map (old_gid);
+      unsigned int outer = v >> 16;
+      output_map.arrayZ[new_gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
+    }
+  }
+
+  bool remap_after_instantiation (const hb_subset_plan_t *plan,
+                                  const hb_map_t& varidx_map)
+  {
+    /* recalculate bit_count after remapping */
+    outer_bit_count = 1;
+    inner_bit_count = 1;
+
+    for (const auto &_ : plan->new_to_old_gid_list)
+    {
+      hb_codepoint_t new_gid = _.first;
+      if (unlikely (new_gid >= map_count)) break;
+
+      uint32_t v = output_map.arrayZ[new_gid];
+      uint32_t *new_varidx;
+      if (!varidx_map.has (v, &new_varidx))
+        return false;
+
+      output_map.arrayZ[new_gid] = *new_varidx;
+
+      unsigned outer = (*new_varidx) >> 16;
+      unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer);
+      outer_bit_count = hb_max (bit_count, outer_bit_count);
+
+      unsigned inner = (*new_varidx) & 0xFFFF;
+      bit_count = (inner == 0) ? 1 : hb_bit_storage (inner);
+      inner_bit_count = hb_max (bit_count, inner_bit_count);
     }
+    return true;
   }
 
   unsigned int get_inner_bit_count () const { return inner_bit_count; }
@@ -180,7 +204,7 @@
     if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
 
     bool retain_adv_map = false;
-    index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan);
+    index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan, false);
     if (index_maps[0] == &Null (DeltaSetIndexMap))
     {
       retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS;
@@ -197,12 +221,10 @@
 
     if (retain_adv_map)
     {
-      for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
+      for (const auto &_ : plan->new_to_old_gid_list)
       {
-        if (inner_sets[0]->has (gid))
-          inner_maps[0].add (gid);
-        else
-          inner_maps[0].skip ();
+        hb_codepoint_t old_gid = _.second;
+        inner_maps[0].add (old_gid);
       }
     }
     else
@@ -219,6 +241,16 @@
       index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan);
   }
 
+  /* remap */
+  bool remap_index_map_plans (const hb_subset_plan_t *plan,
+                              const hb_map_t& varidx_map)
+  {
+    for (unsigned i = 0; i < index_map_plans.length; i++)
+      if (!index_map_plans[i].remap_after_instantiation (plan, varidx_map))
+        return false;
+    return true;
+  }
+
   void fini ()
   {
     for (unsigned int i = 0; i < inner_sets.length; i++)
@@ -297,6 +329,9 @@
   bool _subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
     hvarvvar_subset_plan_t      hvar_plan;
     hb_vector_t
                                 index_maps;
@@ -310,11 +345,37 @@
     out->version.major = 1;
     out->version.minor = 0;
 
-    if (unlikely (!out->varStore
-                      .serialize_serialize (c->serializer,
-                                            hvar_plan.var_store,
-                                            hvar_plan.inner_maps.as_array ())))
+    if (c->plan->normalized_coords)
+    {
+      item_variations_t item_vars;
+      if (!item_vars.instantiate (this+varStore, c->plan,
+                                  advMap == 0 ? false : true,
+                                  false, /* use_no_variation_idx = false */
+                                  hvar_plan.inner_maps.as_array ()))
+        return_trace (false);
+
+      if (!out->varStore.serialize_serialize (c->serializer,
+                                              item_vars.has_long_word (),
+                                              c->plan->axis_tags,
+                                              item_vars.get_region_list (),
+                                              item_vars.get_vardata_encodings ()))
+        return_trace (false);
+
+      /* if varstore is optimized, remap output_map */
+      if (advMap)
+      {
+        if (!hvar_plan.remap_index_map_plans (c->plan, item_vars.get_varidx_map ()))
+          return_trace (false);
+      }
+    }
+    else
+    {
+      if (unlikely (!out->varStore
+                    .serialize_serialize (c->serializer,
+                                          hvar_plan.var_store,
+                                          hvar_plan.inner_maps.as_array ())))
       return_trace (false);
+    }
 
     return_trace (out->T::serialize_index_maps (c->serializer,
                                                 hvar_plan.index_map_plans.as_array ()));
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -27,7 +27,7 @@
 #ifndef HB_OT_VAR_MVAR_TABLE_HH
 #define HB_OT_VAR_MVAR_TABLE_HH
 
-#include "hb-ot-layout-common.hh"
+#include "hb-ot-var-common.hh"
 
 
 namespace OT {
@@ -41,6 +41,19 @@
     return_trace (c->check_struct (this));
   }
 
+  bool subset (hb_subset_context_t *c,
+               const hb_map_t& varidx_map) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    hb_codepoint_t *new_idx;
+    return_trace (c->serializer->check_assign (out->varIdx,
+                                               (varidx_map.has (varIdx, &new_idx)) ? *new_idx : HB_OT_LAYOUT_NO_VARIATIONS_INDEX,
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   public:
   Tag           valueTag;       /* Four-byte tag identifying a font-wide measure. */
   VarIdx        varIdx;         /* Outer/inner index into VariationStore item. */
@@ -73,6 +86,47 @@
                                   valueRecordSize));
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+#ifdef HB_NO_VAR
+    return_trace (false);
+#endif
+
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    MVAR *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->version = version;
+    out->reserved = reserved;
+    out->valueRecordSize = valueRecordSize;
+    out->valueRecordCount = valueRecordCount;
+
+    item_variations_t item_vars;
+    const VariationStore& src_var_store = this+varStore;
+
+    if (!item_vars.instantiate (src_var_store, c->plan))
+      return_trace (false);
+
+    /* serialize varstore */
+    if (!out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (),
+                                            c->plan->axis_tags,
+                                            item_vars.get_region_list (),
+                                            item_vars.get_vardata_encodings ()))
+      return_trace (false);
+
+    /* serialize value records array */
+    unsigned value_rec_count = valueRecordCount;
+    const VariationValueRecord *record = reinterpret_cast (valuesZ.arrayZ);
+    for (unsigned i = 0; i < value_rec_count; i++)
+    {
+      if (!record->subset (c, item_vars.get_varidx_map ())) return_trace (false);
+      record++;
+    }
+    return_trace (true);
+  }
+
   float get_var (hb_tag_t tag,
                  const int *coords, unsigned int coord_count) const
   {
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -90,7 +90,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    VORG *vorg_prime = c->serializer->start_embed ();
+    auto *vorg_prime = c->serializer->start_embed ();
     if (unlikely (!c->serializer->check_success (vorg_prime))) return_trace (false);
 
     auto it =
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-paint.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-paint.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-paint.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-paint.cc	2024-01-16 16:19:00.000000000 +0000
@@ -54,6 +54,12 @@
 hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data,
                             void *user_data) {}
 
+static hb_bool_t
+hb_paint_color_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
+                          hb_codepoint_t glyph,
+                          hb_font_t *font,
+                          void *user_data) { return false; }
+
 static void
 hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
                               hb_codepoint_t glyph,
@@ -474,6 +480,25 @@
 }
 
 /**
+ * hb_paint_color_glyph:
+ * @funcs: paint functions
+ * @paint_data: associated data passed by the caller
+ * @glyph: the glyph ID
+ * @font: the font
+ *
+ * Perform a "color-glyph" paint operation.
+ *
+ * Since: 8.2.0
+ */
+hb_bool_t
+hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data,
+                      hb_codepoint_t glyph,
+                      hb_font_t *font)
+{
+  return funcs->color_glyph (paint_data, glyph, font);
+}
+
+/**
  * hb_paint_push_clip_glyph:
  * @funcs: paint functions
  * @paint_data: associated data passed by the caller
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-paint.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-paint.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-paint.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-paint.h	2024-01-16 16:19:00.000000000 +0000
@@ -137,6 +137,26 @@
                                                void *user_data);
 
 /**
+ * hb_paint_color_glyph_func_t:
+ * @funcs: paint functions object
+ * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
+ * @glyph: the glyph ID
+ * @font: the font
+ * @user_data: User data pointer passed to hb_paint_funcs_set_color_glyph_func()
+ *
+ * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index.
+ *
+ * Return value: %true if the glyph was painted, %false otherwise.
+ *
+ * Since: 8.2.0
+ */
+typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs,
+                                                  void *paint_data,
+                                                  hb_codepoint_t glyph,
+                                                  hb_font_t *font,
+                                                  void *user_data);
+
+/**
  * hb_paint_push_clip_glyph_func_t:
  * @funcs: paint functions object
  * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
@@ -724,6 +744,23 @@
                                        hb_destroy_func_t              destroy);
 
 /**
+ * hb_paint_funcs_set_color_glyph_func:
+ * @funcs: A paint functions struct
+ * @func: (closure user_data) (destroy destroy) (scope notified): The color-glyph callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): Function to call when @user_data is no longer needed
+ *
+ * Sets the color-glyph callback on the paint functions struct.
+ *
+ * Since: 8.2.0
+ */
+HB_EXTERN void
+hb_paint_funcs_set_color_glyph_func (hb_paint_funcs_t                *funcs,
+                                     hb_paint_color_glyph_func_t     func,
+                                     void                            *user_data,
+                                     hb_destroy_func_t                destroy);
+
+/**
  * hb_paint_funcs_set_push_clip_glyph_func:
  * @funcs: A paint functions struct
  * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-glyph callback
@@ -922,6 +959,11 @@
 HB_EXTERN void
 hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data);
 
+HB_EXTERN hb_bool_t
+hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data,
+                      hb_codepoint_t glyph,
+                      hb_font_t *font);
+
 HB_EXTERN void
 hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data,
                           hb_codepoint_t glyph,
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-paint.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-paint.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-paint.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-paint.hh	2024-01-16 16:19:00.000000000 +0000
@@ -32,6 +32,7 @@
 #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \
   HB_PAINT_FUNC_IMPLEMENT (push_transform) \
   HB_PAINT_FUNC_IMPLEMENT (pop_transform) \
+  HB_PAINT_FUNC_IMPLEMENT (color_glyph) \
   HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \
   HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \
   HB_PAINT_FUNC_IMPLEMENT (pop_clip) \
@@ -77,6 +78,13 @@
   void pop_transform (void *paint_data)
   { func.pop_transform (this, paint_data,
                         !user_data ? nullptr : user_data->pop_transform); }
+  bool color_glyph (void *paint_data,
+                    hb_codepoint_t glyph,
+                    hb_font_t *font)
+  { return func.color_glyph (this, paint_data,
+                             glyph,
+                             font,
+                             !user_data ? nullptr : user_data->push_clip_glyph); }
   void push_clip_glyph (void *paint_data,
                         hb_codepoint_t glyph,
                         hb_font_t *font)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-pool.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-pool.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-pool.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-pool.hh	2024-01-16 16:19:00.000000000 +0000
@@ -58,7 +58,7 @@
     if (unlikely (!next))
     {
       if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr;
-      chunk_t *chunk = (chunk_t *) hb_calloc (1, sizeof (chunk_t));
+      chunk_t *chunk = (chunk_t *) hb_malloc (sizeof (chunk_t));
       if (unlikely (!chunk)) return nullptr;
       chunks.push (chunk);
       next = chunk->thread ();
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh	2024-01-16 16:19:00.000000000 +0000
@@ -42,10 +42,11 @@
  * priority of its children. The heap is stored in an array, with the
  * children of node i stored at indices 2i + 1 and 2i + 2.
  */
+template 
 struct hb_priority_queue_t
 {
  private:
-  typedef hb_pair_t item_t;
+  typedef hb_pair_t item_t;
   hb_vector_t heap;
 
  public:
@@ -54,13 +55,19 @@
 
   bool in_error () const { return heap.in_error (); }
 
-  void insert (int64_t priority, unsigned value)
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
+  void insert (K priority, unsigned value)
   {
     heap.push (item_t (priority, value));
     if (unlikely (heap.in_error ())) return;
     bubble_up (heap.length - 1);
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   item_t pop_minimum ()
   {
     assert (!is_empty ());
@@ -106,8 +113,10 @@
     return 2 * index + 2;
   }
 
+  HB_ALWAYS_INLINE
   void bubble_down (unsigned index)
   {
+    repeat:
     assert (index < heap.length);
 
     unsigned left = left_child (index);
@@ -123,19 +132,21 @@
         && (!has_right || heap.arrayZ[index].first <= heap.arrayZ[right].first))
       return;
 
+    unsigned child;
     if (!has_right || heap.arrayZ[left].first < heap.arrayZ[right].first)
-    {
-      swap (index, left);
-      bubble_down (left);
-      return;
-    }
+      child = left;
+    else
+      child = right;
 
-    swap (index, right);
-    bubble_down (right);
+    swap (index, child);
+    index = child;
+    goto repeat;
   }
 
+  HB_ALWAYS_INLINE
   void bubble_up (unsigned index)
   {
+    repeat:
     assert (index < heap.length);
 
     if (index == 0) return;
@@ -145,7 +156,8 @@
       return;
 
     swap (index, parent_index);
-    bubble_up (parent_index);
+    index = parent_index;
+    goto repeat;
   }
 
   void swap (unsigned a, unsigned b)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh	2024-01-16 16:19:00.000000000 +0000
@@ -79,7 +79,12 @@
   //                pass after this processing is done. Not super necessary as splits are
   //                only done where overflow is likely, so de-dup probably will get undone
   //                later anyways.
-  for (unsigned lookup_index : ext_context.lookups.keys ())
+
+  // The loop below can modify the contents of ext_context.lookups if new subtables are added
+  // to a lookup during a split. So save the initial set of lookup indices so the iteration doesn't
+  // risk access free'd memory if ext_context.lookups gets resized.
+  hb_set_t lookup_indices(ext_context.lookups.keys ());
+  for (unsigned lookup_index : lookup_indices)
   {
     graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
     if (!lookup->split_subtables_if_needed (ext_context, lookup_index))
@@ -114,11 +119,15 @@
   // TODO(grieger): skip this for the 24 bit case.
   if (!ext_context.lookups) return true;
 
+  unsigned total_lookup_table_sizes = 0;
   hb_vector_t lookup_sizes;
   lookup_sizes.alloc (ext_context.lookups.get_population (), true);
 
   for (unsigned lookup_index : ext_context.lookups.keys ())
   {
+    const auto& lookup_v = ext_context.graph.vertices_[lookup_index];
+    total_lookup_table_sizes += lookup_v.table_size ();
+
     const graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
     hb_set_t visited;
     lookup_sizes.push (lookup_size_t {
@@ -131,14 +140,16 @@
   lookup_sizes.qsort ();
 
   size_t lookup_list_size = ext_context.graph.vertices_[ext_context.lookup_list_index].table_size ();
-  size_t l2_l3_size = lookup_list_size; // Lookup List + Lookups
-  size_t l3_l4_size = 0; // Lookups + SubTables
+  size_t l2_l3_size = lookup_list_size + total_lookup_table_sizes; // Lookup List + Lookups
+  size_t l3_l4_size = total_lookup_table_sizes; // Lookups + SubTables
   size_t l4_plus_size = 0; // SubTables + their descendants
 
   // Start by assuming all lookups are using extension subtables, this size will be removed later
   // if it's decided to not make a lookup extension.
   for (auto p : lookup_sizes)
   {
+    // TODO(garretrieger): this overestimates the extension subtables size because some extension subtables may be
+    //                     reused. However, we can't correct this until we have connected component analysis in place.
     unsigned subtables_size = p.num_subtables * 8;
     l3_l4_size += subtables_size;
     l4_plus_size += subtables_size;
@@ -159,8 +170,7 @@
       size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size;
       size_t remaining_size = p.size - subtables_size - lookup_size;
 
-      l2_l3_size   += lookup_size;
-      l3_l4_size   += lookup_size + subtables_size;
+      l3_l4_size   += subtables_size;
       l3_l4_size   -= p.num_subtables * 8;
       l4_plus_size += subtables_size + remaining_size;
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh	2024-01-16 16:19:00.000000000 +0000
@@ -122,12 +122,14 @@
 {
   hb_sanitize_context_t () :
         start (nullptr), end (nullptr),
+        length (0),
         max_ops (0), max_subtables (0),
         recursion_depth (0),
         writable (false), edit_count (0),
         blob (nullptr),
         num_glyphs (65536),
-        num_glyphs_set (false) {}
+        num_glyphs_set (false),
+        lazy_some_gpos (false) {}
 
   const char *get_name () { return "SANITIZE"; }
   template 
@@ -155,6 +157,19 @@
   dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
   ( _dispatch (obj, hb_prioritize, std::forward (ds)...) )
 
+  hb_sanitize_context_t (hb_blob_t *b) : hb_sanitize_context_t ()
+  {
+    init (b);
+
+    if (blob)
+      start_processing ();
+  }
+
+  ~hb_sanitize_context_t ()
+  {
+    if (blob)
+      end_processing ();
+  }
 
   void init (hb_blob_t *b)
   {
@@ -180,11 +195,15 @@
 
     const char *obj_start = (const char *) obj;
     if (unlikely (obj_start < this->start || this->end <= obj_start))
+    {
       this->start = this->end = nullptr;
+      this->length = 0;
+    }
     else
     {
       this->start = obj_start;
       this->end   = obj_start + hb_min (size_t (this->end - obj_start), obj->get_size ());
+      this->length = this->end - this->start;
     }
   }
 
@@ -192,6 +211,7 @@
   {
     this->start = this->blob->data;
     this->end = this->start + this->blob->length;
+    this->length = this->end - this->start;
     assert (this->start <= this->end); /* Must not overflow. */
   }
 
@@ -224,6 +244,7 @@
     hb_blob_destroy (this->blob);
     this->blob = nullptr;
     this->start = this->end = nullptr;
+    this->length = 0;
   }
 
   unsigned get_edit_count () { return edit_count; }
@@ -237,18 +258,20 @@
       this->max_ops = -1;
       return false;
     }
-    return (this->max_ops -= (int) count) > 0;
+    this->max_ops -= (int) count;
+    return true;
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool check_range (const void *base,
                     unsigned int len) const
   {
     const char *p = (const char *) base;
-    bool ok = !len ||
-              (this->start <= p &&
-               p <= this->end &&
-               (unsigned int) (this->end - p) >= len &&
-               (this->max_ops -= len) > 0);
+    bool ok = (uintptr_t) (p - this->start) <= this->length &&
+              (unsigned int) (this->end - p) >= len &&
+              ((this->max_ops -= len) > 0);
 
     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
                      "check_range [%p..%p]"
@@ -259,6 +282,43 @@
 
     return likely (ok);
   }
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
+  bool check_range_fast (const void *base,
+                         unsigned int len) const
+  {
+    const char *p = (const char *) base;
+    bool ok = ((uintptr_t) (p - this->start) <= this->length &&
+               (unsigned int) (this->end - p) >= len);
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+                     "check_range_fast [%p..%p]"
+                     " (%u bytes) in [%p..%p] -> %s",
+                     p, p + len, len,
+                     this->start, this->end,
+                     ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
+
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
+  bool check_point (const void *base) const
+  {
+    const char *p = (const char *) base;
+    bool ok = (uintptr_t) (p - this->start) <= this->length;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+                     "check_point [%p]"
+                     " in [%p..%p] -> %s",
+                     p,
+                     this->start, this->end,
+                     ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
 
   template 
   bool check_range (const T *base,
@@ -282,6 +342,20 @@
   }
 
   template 
+  HB_ALWAYS_INLINE
+  bool check_array_sized (const T *base, unsigned int len, unsigned len_size) const
+  {
+    if (len_size >= 4)
+    {
+      if (unlikely (hb_unsigned_mul_overflows (len, hb_static_size (T), &len)))
+        return false;
+    }
+    else
+      len = len * hb_static_size (T);
+    return this->check_range (base, len);
+  }
+
+  template 
   bool check_array (const T *base, unsigned int len) const
   {
     return this->check_range (base, len, hb_static_size (T));
@@ -292,7 +366,7 @@
                     unsigned int a,
                     unsigned int b) const
   {
-    return this->check_range (base, a, b, hb_static_size (T));
+    return this->check_range (base, hb_static_size (T), a, b);
   }
 
   bool check_start_recursion (int max_depth)
@@ -308,8 +382,16 @@
   }
 
   template 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool check_struct (const Type *obj) const
-  { return likely (this->check_range (obj, obj->min_size)); }
+  {
+    if (sizeof (uintptr_t) == sizeof (uint32_t))
+      return likely (this->check_range_fast (obj, obj->min_size));
+    else
+      return likely (this->check_point ((const char *) obj + obj->min_size));
+  }
 
   bool may_edit (const void *base, unsigned int len)
   {
@@ -371,7 +453,7 @@
         edit_count = 0;
         sane = t->sanitize (this);
         if (edit_count) {
-          DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILLING", edit_count);
+          DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILING", edit_count);
           sane = false;
         }
       }
@@ -416,6 +498,7 @@
   }
 
   const char *start, *end;
+  unsigned length;
   mutable int max_ops, max_subtables;
   private:
   int recursion_depth;
@@ -424,6 +507,8 @@
   hb_blob_t *blob;
   unsigned int num_glyphs;
   bool  num_glyphs_set;
+  public:
+  bool lazy_some_gpos;
 };
 
 struct hb_sanitize_with_object_t
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh	2024-01-16 16:19:00.000000000 +0000
@@ -113,7 +113,7 @@
     {
       // Virtual links aren't considered for equality since they don't affect the functionality
       // of the object.
-      return hb_bytes_t (head, tail - head).hash () ^
+      return hb_bytes_t (head, hb_min (128, tail - head)).hash () ^
           real_links.as_bytes ().hash ();
     }
 
@@ -172,8 +172,14 @@
   };
 
   snapshot_t snapshot ()
-  { return snapshot_t {
-      head, tail, current, current->real_links.length, current->virtual_links.length, errors }; }
+  {
+    return snapshot_t {
+      head, tail, current,
+      current ? current->real_links.length : 0,
+      current ? current->virtual_links.length : 0,
+      errors
+     };
+  }
 
   hb_serialize_context_t (void *start_, unsigned int size) :
     start ((char *) start_),
@@ -260,7 +266,8 @@
            propagate_error (std::forward (os)...); }
 
   /* To be called around main operation. */
-  template 
+  template 
+  __attribute__((returns_nonnull))
   Type *start_serialize ()
   {
     DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
@@ -303,6 +310,7 @@
   }
 
   template 
+  __attribute__((returns_nonnull))
   Type *push ()
   {
     if (unlikely (in_error ())) return start_embed ();
@@ -323,6 +331,8 @@
   {
     object_t *obj = current;
     if (unlikely (!obj)) return;
+    // Allow cleanup when we've error'd out on int overflows which don't compromise
+    // the serializer state.
     if (unlikely (in_error() && !only_overflow ())) return;
 
     current = current->next;
@@ -340,7 +350,9 @@
   {
     object_t *obj = current;
     if (unlikely (!obj)) return 0;
-    if (unlikely (in_error())) return 0;
+    // Allow cleanup when we've error'd out on int overflows which don't compromise
+    // the serializer state.
+    if (unlikely (in_error()  && !only_overflow ())) return 0;
 
     current = current->next;
     obj->tail = head;
@@ -405,8 +417,11 @@
     // Overflows that happened after the snapshot will be erased by the revert.
     if (unlikely (in_error () && !only_overflow ())) return;
     assert (snap.current == current);
-    current->real_links.shrink (snap.num_real_links);
-    current->virtual_links.shrink (snap.num_virtual_links);
+    if (current)
+    {
+      current->real_links.shrink (snap.num_real_links);
+      current->virtual_links.shrink (snap.num_virtual_links);
+    }
     errors = snap.errors;
     revert (snap.head, snap.tail);
   }
@@ -563,13 +578,15 @@
   {
     unsigned int l = length () % alignment;
     if (l)
-      allocate_size (alignment - l);
+      (void) allocate_size (alignment - l);
   }
 
   template 
+  __attribute__((returns_nonnull))
   Type *start_embed (const Type *obj HB_UNUSED = nullptr) const
   { return reinterpret_cast (this->head); }
   template 
+  __attribute__((returns_nonnull))
   Type *start_embed (const Type &obj) const
   { return start_embed (std::addressof (obj)); }
 
@@ -597,6 +614,7 @@
   }
 
   template 
+  HB_NODISCARD
   Type *allocate_size (size_t size, bool clear = true)
   {
     if (unlikely (in_error ())) return nullptr;
@@ -618,6 +636,7 @@
   { return this->allocate_size (Type::min_size); }
 
   template 
+  HB_NODISCARD
   Type *embed (const Type *obj)
   {
     unsigned int size = obj->get_size ();
@@ -627,6 +646,7 @@
     return ret;
   }
   template 
+  HB_NODISCARD
   Type *embed (const Type &obj)
   { return embed (std::addressof (obj)); }
   char *embed (const char *obj, unsigned size)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh	2024-01-16 16:19:00.000000000 +0000
@@ -45,10 +45,16 @@
  * a lookup's or subtable's Coverage table(s), and then when we
  * want to apply the lookup or subtable to a glyph, before trying
  * to apply, we ask the filter if the glyph may be covered. If it's
- * not, we return early.
+ * not, we return early.  We can also match a digest against another
+ * digest.
  *
- * We use these filters both at the lookup-level, and then again,
- * at the subtable-level. Both have performance win.
+ * We use these filters at three levels:
+ *   - If the digest for all the glyphs in the buffer as a whole
+ *     does not match the digest for the lookup, skip the lookup.
+ *   - For each glyph, if it doesn't match the lookup digest,
+ *     skip it.
+ *   - For each glyph, if it doesn't match the subtable digest,
+ *     skip it.
  *
  * The main filter we use is a combination of three bits-pattern
  * filters. A bits-pattern filter checks a number of bits (5 or 6)
@@ -82,14 +88,19 @@
 
   bool add_range (hb_codepoint_t a, hb_codepoint_t b)
   {
+    if (mask == (mask_t) -1) return false;
     if ((b >> shift) - (a >> shift) >= mask_bits - 1)
+    {
       mask = (mask_t) -1;
-    else {
+      return false;
+    }
+    else
+    {
       mask_t ma = mask_for (a);
       mask_t mb = mask_for (b);
       mask |= mb + (mb - ma) - (mb < ma);
+      return true;
     }
-    return true;
   }
 
   template 
@@ -148,8 +159,7 @@
 
   bool add_range (hb_codepoint_t a, hb_codepoint_t b)
   {
-    return head.add_range (a, b) &&
-           tail.add_range (a, b);
+    return (int) head.add_range (a, b) | (int) tail.add_range (a, b);
   }
   template 
   void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set.cc	2024-01-16 16:19:00.000000000 +0000
@@ -200,7 +200,7 @@
 void
 hb_set_clear (hb_set_t *set)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->clear ();
 }
 
@@ -251,7 +251,7 @@
 hb_set_add (hb_set_t       *set,
             hb_codepoint_t  codepoint)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->add (codepoint);
 }
 
@@ -272,7 +272,7 @@
                          const hb_codepoint_t *sorted_codepoints,
                          unsigned int          num_codepoints)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->add_sorted_array (sorted_codepoints,
                          num_codepoints,
                          sizeof(hb_codepoint_t));
@@ -294,7 +294,7 @@
                   hb_codepoint_t  first,
                   hb_codepoint_t  last)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->add_range (first, last);
 }
 
@@ -311,7 +311,7 @@
 hb_set_del (hb_set_t       *set,
             hb_codepoint_t  codepoint)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->del (codepoint);
 }
 
@@ -334,7 +334,7 @@
                   hb_codepoint_t  first,
                   hb_codepoint_t  last)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->del_range (first, last);
 }
 
@@ -405,7 +405,7 @@
 hb_set_set (hb_set_t       *set,
             const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->set (*other);
 }
 
@@ -422,7 +422,7 @@
 hb_set_union (hb_set_t       *set,
               const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->union_ (*other);
 }
 
@@ -439,7 +439,7 @@
 hb_set_intersect (hb_set_t       *set,
                   const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->intersect (*other);
 }
 
@@ -456,7 +456,7 @@
 hb_set_subtract (hb_set_t       *set,
                  const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->subtract (*other);
 }
 
@@ -474,7 +474,7 @@
 hb_set_symmetric_difference (hb_set_t       *set,
                              const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->symmetric_difference (*other);
 }
 
@@ -489,7 +489,7 @@
 void
 hb_set_invert (hb_set_t *set)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->invert ();
 }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set.h	2024-01-16 16:19:00.000000000 +0000
@@ -43,7 +43,7 @@
  *
  * Since: 0.9.21
  */
-#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
+#define HB_SET_VALUE_INVALID HB_CODEPOINT_INVALID
 
 /**
  * hb_set_t:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-set.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-set.hh	2024-01-16 16:19:00.000000000 +0000
@@ -115,7 +115,7 @@
   /* Sink interface. */
   hb_sparseset_t& operator << (hb_codepoint_t v)
   { add (v); return *this; }
-  hb_sparseset_t& operator << (const hb_pair_t& range)
+  hb_sparseset_t& operator << (const hb_codepoint_pair_t& range)
   { add_range (range.first, range.second); return *this; }
 
   bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
@@ -174,7 +174,7 @@
 
   hb_set_t& operator << (hb_codepoint_t v)
   { sparseset::operator<< (v); return *this; }
-  hb_set_t& operator << (const hb_pair_t& range)
+  hb_set_t& operator << (const hb_codepoint_pair_t& range)
   { sparseset::operator<< (range); return *this; }
 };
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-shape.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-shape.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-shape.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-shape.cc	2024-01-16 16:19:00.000000000 +0000
@@ -220,7 +220,7 @@
   assert (buffer->ensure (text.length));
   buffer->have_positions = false;
   buffer->len = text.length;
-  memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0]));
+  hb_memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0]));
   hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
 }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh	2024-01-16 16:19:00.000000000 +0000
@@ -33,6 +33,11 @@
 
 /* v--- Add new shapers in the right place here. */
 
+#ifdef HAVE_WASM
+/* Only picks up fonts that have a "Wasm" table. */
+HB_SHAPER_IMPLEMENT (wasm)
+#endif
+
 #ifdef HAVE_GRAPHITE2
 /* Only picks up fonts that have a "Silf" table. */
 HB_SHAPER_IMPLEMENT (graphite2)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-static.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-static.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-static.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-static.cc	2024-01-16 16:19:00.000000000 +0000
@@ -31,6 +31,7 @@
 
 #include "hb-aat-layout-common.hh"
 #include "hb-aat-layout-feat-table.hh"
+#include "hb-cff-interp-common.hh"
 #include "hb-ot-layout-common.hh"
 #include "hb-ot-cmap-table.hh"
 #include "OT/Color/COLR/COLR.hh"
@@ -58,6 +59,8 @@
 /* hb_map_t */
 
 const hb_codepoint_t minus_1 = -1;
+static const unsigned char static_endchar_str[] = {OpCode_endchar};
+const unsigned char *endchar_str = static_endchar_str;
 
 /* hb_face_t */
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh	2024-01-16 16:19:00.000000000 +0000
@@ -42,7 +42,9 @@
 
 namespace OT {
 struct SubtableUnicodesCache;
-};
+struct cff1_subset_accelerator_t;
+struct cff2_subset_accelerator_t;
+}
 
 struct hb_subset_accelerator_t
 {
@@ -51,15 +53,17 @@
     return &_hb_subset_accelerator_user_data_key;
   }
 
-  static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_,
-                                         const hb_multimap_t gid_to_unicodes_,
+  static hb_subset_accelerator_t* create(hb_face_t *source,
+                                         const hb_map_t& unicode_to_gid_,
                                          const hb_set_t& unicodes_,
                                          bool has_seac_) {
     hb_subset_accelerator_t* accel =
         (hb_subset_accelerator_t*) hb_calloc (1, sizeof(hb_subset_accelerator_t));
 
-    new (accel) hb_subset_accelerator_t (unicode_to_gid_,
-                                         gid_to_unicodes_,
+    if (unlikely (!accel)) return accel;
+
+    new (accel) hb_subset_accelerator_t (source,
+                                         unicode_to_gid_,
                                          unicodes_,
                                          has_seac_);
 
@@ -77,36 +81,36 @@
     hb_free (accel);
   }
 
-  hb_subset_accelerator_t (const hb_map_t& unicode_to_gid_,
-                           const hb_multimap_t& gid_to_unicodes_,
+  hb_subset_accelerator_t (hb_face_t *source,
+                           const hb_map_t& unicode_to_gid_,
                            const hb_set_t& unicodes_,
                            bool has_seac_) :
     unicode_to_gid(unicode_to_gid_),
-    gid_to_unicodes (gid_to_unicodes_),
     unicodes(unicodes_),
     cmap_cache(nullptr),
     destroy_cmap_cache(nullptr),
     has_seac(has_seac_),
-    cff_accelerator(nullptr),
-    destroy_cff_accelerator(nullptr) {}
-
-  ~hb_subset_accelerator_t ()
+    source(hb_face_reference (source))
   {
-    if (cff_accelerator && destroy_cff_accelerator)
-      destroy_cff_accelerator ((void*) cff_accelerator);
-
-    if (cmap_cache && destroy_cmap_cache)
-      destroy_cmap_cache ((void*) cmap_cache);
+    gid_to_unicodes.alloc (unicode_to_gid.get_population ());
+    for (const auto &_ : unicode_to_gid)
+    {
+      auto unicode = _.first;
+      auto gid = _.second;
+      gid_to_unicodes.add (gid, unicode);
+    }
   }
 
+  HB_INTERNAL ~hb_subset_accelerator_t ();
+
   // Generic
 
   mutable hb_mutex_t sanitized_table_cache_lock;
   mutable hb_hashmap_t> sanitized_table_cache;
 
-  const hb_map_t unicode_to_gid;
-  const hb_multimap_t gid_to_unicodes;
-  const hb_set_t unicodes;
+  hb_map_t unicode_to_gid;
+  hb_multimap_t gid_to_unicodes;
+  hb_set_t unicodes;
 
   // cmap
   const OT::SubtableUnicodesCache* cmap_cache;
@@ -114,8 +118,6 @@
 
   // CFF
   bool has_seac;
-  const CFF::cff_subset_accelerator_t* cff_accelerator;
-  hb_destroy_func_t destroy_cff_accelerator;
 
   // TODO(garretrieger): cumulative glyf checksum map
 
@@ -126,6 +128,13 @@
            unicodes.in_error () ||
            sanitized_table_cache.in_error ();
   }
+
+  hb_face_t *source;
+#ifndef HB_NO_SUBSET_CFF
+  // These have to be immediately after source:
+  mutable hb_face_lazy_loader_t cff1_accel;
+  mutable hb_face_lazy_loader_t cff2_accel;
+#endif
 };
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc	2024-01-16 16:19:00.000000000 +0000
@@ -68,24 +68,35 @@
     /* use hb_set to determine the subset of font dicts */
     hb_set_t set;
     hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
-    for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
+    hb_pair_t last_range {0, 0};
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    auto _ = *it;
+    for (hb_codepoint_t gid = 0; gid < subset_num_glyphs; gid++)
     {
-      hb_codepoint_t glyph;
-      hb_codepoint_t fd;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
+      hb_codepoint_t old_glyph;
+      if (gid == _.first)
+      {
+        old_glyph = _.second;
+        _ = *++it;
+      }
+      else
       {
         /* fonttools retains FDSelect & font dicts for missing glyphs. do the same */
-        glyph = i;
+        old_glyph = gid;
       }
-      fd = src.get_fd (glyph);
-      set.add (fd);
+      if (old_glyph >= last_range.second)
+        last_range = src.get_fd_range (old_glyph);
+      unsigned fd = last_range.first;
 
       if (fd != prev_fd)
       {
+        set.add (fd);
         num_ranges++;
         prev_fd = fd;
-        code_pair_t pair = { fd, i };
-        fdselect_ranges.push (pair);
+        fdselect_ranges.push (code_pair_t { fd, gid });
+
+        if (gid == old_glyph)
+          gid = hb_min (_.first - 1, last_range.second - 1);
       }
     }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh	2024-01-16 16:19:00.000000000 +0000
@@ -480,6 +480,7 @@
       const hb_vector_t& parsed_local_subrs) {
     cff_subset_accelerator_t* accel =
         (cff_subset_accelerator_t*) hb_malloc (sizeof(cff_subset_accelerator_t));
+    if (unlikely (!accel)) return nullptr;
     new (accel) cff_subset_accelerator_t (original_blob,
                                           parsed_charstrings,
                                           parsed_global_subrs,
@@ -510,15 +511,21 @@
     original_blob = hb_blob_reference (original_blob_);
   }
 
-  ~cff_subset_accelerator_t() {
+  ~cff_subset_accelerator_t()
+  {
     hb_blob_destroy (original_blob);
-    hb_map_destroy (glyph_to_sid_map.get_relaxed ());
+    auto *mapping = glyph_to_sid_map.get_relaxed ();
+    if (mapping)
+    {
+      mapping->~glyph_to_sid_map_t ();
+      hb_free (mapping);
+    }
   }
 
   parsed_cs_str_vec_t parsed_charstrings;
   parsed_cs_str_vec_t parsed_global_subrs;
   hb_vector_t parsed_local_subrs;
-  mutable hb_atomic_ptr_t glyph_to_sid_map = nullptr;
+  mutable hb_atomic_ptr_t glyph_to_sid_map;
 
  private:
   hb_blob_t* original_blob;
@@ -600,9 +607,8 @@
      * no optimization based on usage counts. fonttools doesn't appear doing that either.
      */
 
-    resize (closure->get_population ());
-    hb_codepoint_t old_num = HB_SET_VALUE_INVALID;
-    while (hb_set_next (closure, &old_num))
+    alloc (closure->get_population ());
+    for (auto old_num : *closure)
       add (old_num);
 
     if (get_population () < 1240)
@@ -672,8 +678,8 @@
   {
     unsigned fd_count = acc.fdCount;
     const cff_subset_accelerator_t* cff_accelerator = nullptr;
-    if (plan->accelerator && plan->accelerator->cff_accelerator) {
-      cff_accelerator = plan->accelerator->cff_accelerator;
+    if (acc.cff_accelerator) {
+      cff_accelerator = acc.cff_accelerator;
       fd_count = cff_accelerator->parsed_local_subrs.length;
     }
 
@@ -709,14 +715,13 @@
     }
 
     /* phase 1 & 2 */
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t  glyph;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
-        continue;
+      hb_codepoint_t new_glyph = _.first;
+      hb_codepoint_t old_glyph = _.second;
 
-      const hb_ubytes_t str = (*acc.charStrings)[glyph];
-      unsigned int fd = acc.fdSelect->get_fd (glyph);
+      const hb_ubytes_t str = (*acc.charStrings)[old_glyph];
+      unsigned int fd = acc.fdSelect->get_fd (old_glyph);
       if (unlikely (fd >= acc.fdCount))
         return false;
 
@@ -725,9 +730,9 @@
         // parsed string already exists in accelerator, copy it and move
         // on.
         if (cached_charstrings)
-          cached_charstrings[i] = &cff_accelerator->parsed_charstrings[glyph];
+          cached_charstrings[new_glyph] = &cff_accelerator->parsed_charstrings[old_glyph];
         else
-          parsed_charstrings[i] = cff_accelerator->parsed_charstrings[glyph];
+          parsed_charstrings[new_glyph] = cff_accelerator->parsed_charstrings[old_glyph];
 
         continue;
       }
@@ -735,8 +740,8 @@
       ENV env (str, acc, fd);
       cs_interpreter_t interp (env);
 
-      parsed_charstrings[i].alloc (str.length);
-      subr_subset_param_t  param (&parsed_charstrings[i],
+      parsed_charstrings[new_glyph].alloc (str.length);
+      subr_subset_param_t  param (&parsed_charstrings[new_glyph],
                                   &parsed_global_subrs_storage,
                                   &parsed_local_subrs_storage[fd],
                                   &closures.global_closure,
@@ -747,12 +752,12 @@
         return false;
 
       /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
-      SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]);
+      SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[new_glyph]);
 
       /* mark hint ops and arguments for drop */
       if ((plan->flags & HB_SUBSET_FLAGS_NO_HINTING) || plan->inprogress_accelerator)
       {
-        subr_subset_param_t  param (&parsed_charstrings[i],
+        subr_subset_param_t  param (&parsed_charstrings[new_glyph],
                                     &parsed_global_subrs_storage,
                                     &parsed_local_subrs_storage[fd],
                                     &closures.global_closure,
@@ -760,21 +765,21 @@
                                     plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
 
         drop_hints_param_t  drop;
-        if (drop_hints_in_str (parsed_charstrings[i], param, drop))
+        if (drop_hints_in_str (parsed_charstrings[new_glyph], param, drop))
         {
-          parsed_charstrings[i].set_hint_dropped ();
+          parsed_charstrings[new_glyph].set_hint_dropped ();
           if (drop.vsindex_dropped)
-            parsed_charstrings[i].set_vsindex_dropped ();
+            parsed_charstrings[new_glyph].set_vsindex_dropped ();
         }
       }
 
-      /* Doing this here one by one instead of compacting all at the en
+      /* Doing this here one by one instead of compacting all at the end
        * has massive peak-memory saving.
        *
        * The compacting both saves memory and makes further operations
        * faster.
        */
-      parsed_charstrings[i].compact ();
+      parsed_charstrings[new_glyph].compact ();
     }
 
     /* Since parsed strings were loaded from accelerator, we still need
@@ -797,23 +802,40 @@
 
   bool encode_charstrings (str_buff_vec_t &buffArray, bool encode_prefix = true) const
   {
-    if (unlikely (!buffArray.resize_exact (plan->num_output_glyphs ())))
+    unsigned num_glyphs = plan->num_output_glyphs ();
+    if (unlikely (!buffArray.resize_exact (num_glyphs)))
       return false;
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    hb_codepoint_t last = 0;
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t  glyph;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
-      {
-        /* add an endchar only charstring for a missing glyph if CFF1 */
-        if (endchar_op != OpCode_Invalid) buffArray.arrayZ[i].push (endchar_op);
-        continue;
-      }
-      unsigned int  fd = acc.fdSelect->get_fd (glyph);
+      hb_codepoint_t gid = _.first;
+      hb_codepoint_t old_glyph = _.second;
+
+      if (endchar_op != OpCode_Invalid)
+        for (; last < gid; last++)
+        {
+          // Hack to point vector to static string.
+          auto &b = buffArray.arrayZ[last];
+          b.length = 1;
+          b.arrayZ = const_cast(endchar_str);
+        }
+
+      last++; // Skip over gid
+      unsigned int  fd = acc.fdSelect->get_fd (old_glyph);
       if (unlikely (fd >= acc.fdCount))
         return false;
-      if (unlikely (!encode_str (get_parsed_charstring (i), fd, buffArray.arrayZ[i], encode_prefix)))
+      if (unlikely (!encode_str (get_parsed_charstring (gid), fd, buffArray.arrayZ[gid], encode_prefix)))
         return false;
     }
+    if (endchar_op != OpCode_Invalid)
+      for (; last < num_glyphs; last++)
+      {
+        // Hack to point vector to static string.
+        auto &b = buffArray.arrayZ[last];
+        b.length = 1;
+        b.arrayZ = const_cast(endchar_str);
+      }
+
     return true;
   }
 
@@ -980,24 +1002,23 @@
                             const hb_vector_t& local_subrs)
   {
     closures.reset ();
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t  glyph;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
-        continue;
-      unsigned int fd = acc.fdSelect->get_fd (glyph);
+      hb_codepoint_t new_glyph = _.first;
+      hb_codepoint_t old_glyph = _.second;
+      unsigned int fd = acc.fdSelect->get_fd (old_glyph);
       if (unlikely (fd >= acc.fdCount))
         return false;
 
       // Note: const cast is safe here because the collect_subr_refs_in_str only performs a
       //       closure and does not modify any of the charstrings.
-      subr_subset_param_t  param (const_cast (&get_parsed_charstring (i)),
+      subr_subset_param_t  param (const_cast (&get_parsed_charstring (new_glyph)),
                                   const_cast (&global_subrs),
                                   const_cast (&local_subrs[fd]),
                                   &closures.global_closure,
                                   &closures.local_closures[fd],
                                   plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
-      collect_subr_refs_in_str (get_parsed_charstring (i), param);
+      collect_subr_refs_in_str (get_parsed_charstring (new_glyph), param);
     }
 
     return true;
@@ -1105,14 +1126,11 @@
 
     compact_parsed_subrs ();
 
-    plan->inprogress_accelerator->cff_accelerator =
+    acc.cff_accelerator =
         cff_subset_accelerator_t::create(acc.blob,
                                          parsed_charstrings,
                                          parsed_global_subrs_storage,
                                          parsed_local_subrs_storage);
-    plan->inprogress_accelerator->destroy_cff_accelerator =
-        cff_subset_accelerator_t::destroy;
-
   }
 
   const parsed_cs_str_t& get_parsed_charstring (unsigned i) const
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc	2024-01-16 16:19:00.000000000 +0000
@@ -32,36 +32,59 @@
 #include "hb-ot-cff1-table.hh"
 #include "hb-set.h"
 #include "hb-bimap.hh"
-#include "hb-subset-cff1.hh"
 #include "hb-subset-plan.hh"
 #include "hb-subset-cff-common.hh"
 #include "hb-cff1-interp-cs.hh"
 
 using namespace CFF;
 
-struct remap_sid_t : hb_inc_bimap_t
+struct remap_sid_t
 {
+  unsigned get_population () const { return vector.length; }
+
+  void alloc (unsigned size)
+  {
+    map.alloc (size);
+    vector.alloc (size, true);
+  }
+
+  bool in_error () const
+  { return map.in_error () || vector.in_error (); }
+
   unsigned int add (unsigned int sid)
   {
-    if ((sid != CFF_UNDEF_SID) && !is_std_std (sid))
-      return offset_sid (hb_inc_bimap_t::add (unoffset_sid (sid)));
-    else
+    if (is_std_str (sid) || (sid == CFF_UNDEF_SID))
       return sid;
+
+    sid = unoffset_sid (sid);
+    unsigned v = next;
+    if (map.set (sid, v, false))
+    {
+      vector.push (sid);
+      next++;
+    }
+    else
+      v = map.get (sid); // already exists
+    return offset_sid (v);
   }
 
   unsigned int operator[] (unsigned int sid) const
   {
-    if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
+    if (is_std_str (sid) || (sid == CFF_UNDEF_SID))
       return sid;
-    else
-      return offset_sid (get (unoffset_sid (sid)));
+
+    return offset_sid (map.get (unoffset_sid (sid)));
   }
 
   static const unsigned int num_std_strings = 391;
 
-  static bool is_std_std (unsigned int sid) { return sid < num_std_strings; }
+  static bool is_std_str (unsigned int sid) { return sid < num_std_strings; }
   static unsigned int offset_sid (unsigned int sid) { return sid + num_std_strings; }
   static unsigned int unoffset_sid (unsigned int sid) { return sid - num_std_strings; }
+  unsigned next = 0;
+
+  hb_map_t map;
+  hb_vector_t vector;
 };
 
 struct cff1_sub_table_info_t : cff_sub_table_info_t
@@ -271,16 +294,17 @@
   /* replace the first glyph ID in the "glyph" field each range with a nLeft value */
   bool complete (unsigned int last_glyph)
   {
-    bool two_byte = false;
+    hb_codepoint_t all_glyphs = 0;
     unsigned count = this->length;
     for (unsigned int i = count; i; i--)
     {
       code_pair_t &pair = arrayZ[i - 1];
       unsigned int nLeft = last_glyph - pair.glyph - 1;
-      two_byte |= nLeft >= 0x100;
+      all_glyphs |= nLeft;
       last_glyph = pair.glyph;
       pair.glyph = nLeft;
     }
+    bool two_byte = all_glyphs >= 0x100;
     return two_byte;
   }
 };
@@ -391,8 +415,10 @@
   }
 };
 
-struct cff_subset_plan {
-  cff_subset_plan ()
+namespace OT {
+struct cff1_subset_plan
+{
+  cff1_subset_plan ()
   {
     for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
       topDictModSIDs[i] = CFF_UNDEF_SID;
@@ -402,7 +428,7 @@
   {
     const Encoding *encoding = acc.encoding;
     unsigned int  size0, size1;
-    hb_codepoint_t  code, last_code = CFF_UNDEF_CODE;
+    unsigned code, last_code = CFF_UNDEF_CODE - 1;
     hb_vector_t supp_codes;
 
     if (unlikely (!subset_enc_code_ranges.resize (0)))
@@ -413,39 +439,42 @@
 
     supp_codes.init ();
 
+    code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
     subset_enc_num_codes = plan->num_output_glyphs () - 1;
     unsigned int glyph;
-    for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    if (it->first == 0) it++;
+    auto _ = *it;
+    for (glyph = 1; glyph < num_glyphs; glyph++)
     {
-      hb_codepoint_t  old_glyph;
-      if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
+      hb_codepoint_t old_glyph;
+      if (glyph == _.first)
       {
-        /* Retain the code for the old missing glyph ID */
+        old_glyph = _.second;
+        _ = *++it;
+      }
+      else
+      {
+        /* Retain the SID for the old missing glyph ID */
         old_glyph = glyph;
       }
-      code = acc.glyph_to_code (old_glyph);
+      code = acc.glyph_to_code (old_glyph, &glyph_to_sid_cache);
       if (code == CFF_UNDEF_CODE)
       {
         subset_enc_num_codes = glyph - 1;
         break;
       }
 
-      if ((last_code == CFF_UNDEF_CODE) || (code != last_code + 1))
-      {
-        code_pair_t pair = { code, glyph };
-        subset_enc_code_ranges.push (pair);
-      }
+      if (code != last_code + 1)
+        subset_enc_code_ranges.push (code_pair_t {code, glyph});
       last_code = code;
 
       if (encoding != &Null (Encoding))
       {
-        hb_codepoint_t  sid = acc.glyph_to_sid (old_glyph);
+        hb_codepoint_t  sid = acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache);
         encoding->get_supplement_codes (sid, supp_codes);
         for (unsigned int i = 0; i < supp_codes.length; i++)
-        {
-          code_pair_t pair = { supp_codes[i], sid };
-          subset_enc_supp_codes.push (pair);
-        }
+          subset_enc_supp_codes.push (code_pair_t {supp_codes[i], sid});
       }
     }
     supp_codes.fini ();
@@ -462,65 +491,93 @@
       subset_enc_format = 1;
   }
 
-  void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
+  bool plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
   {
     unsigned int  size0, size_ranges;
-    hb_codepoint_t  sid, last_sid = CFF_UNDEF_CODE;
+    unsigned last_sid = CFF_UNDEF_CODE - 1;
 
     if (unlikely (!subset_charset_ranges.resize (0)))
     {
       plan->check_success (false);
-      return;
+      return false;
+    }
+
+    code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
+
+    unsigned num_glyphs = plan->num_output_glyphs ();
+
+    if (unlikely (!subset_charset_ranges.alloc (hb_min (num_glyphs,
+                                                        acc.num_charset_entries))))
+    {
+      plan->check_success (false);
+      return false;
     }
 
-    hb_map_t *glyph_to_sid_map = (plan->accelerator && plan->accelerator->cff_accelerator) ?
-                                  plan->accelerator->cff_accelerator->glyph_to_sid_map :
-                                  nullptr;
+    glyph_to_sid_map_t *glyph_to_sid_map = acc.cff_accelerator ?
+                                           acc.cff_accelerator->glyph_to_sid_map.get_acquire () :
+                                           nullptr;
     bool created_map = false;
-    if (!glyph_to_sid_map &&
-        ((plan->accelerator && plan->accelerator->cff_accelerator) ||
-         plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.))
+    if (!glyph_to_sid_map && acc.cff_accelerator)
     {
       created_map = true;
       glyph_to_sid_map = acc.create_glyph_to_sid_map ();
     }
 
-    unsigned int glyph;
-    for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    if (it->first == 0) it++;
+    auto _ = *it;
+    bool not_is_cid = !acc.is_CID ();
+    bool skip = !not_is_cid && glyph_to_sid_map;
+    if (not_is_cid)
+      sidmap.alloc (num_glyphs);
+    for (hb_codepoint_t glyph = 1; glyph < num_glyphs; glyph++)
     {
-      hb_codepoint_t  old_glyph;
-      if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
+      hb_codepoint_t old_glyph;
+      if (glyph == _.first)
+      {
+        old_glyph = _.second;
+        _ = *++it;
+      }
+      else
       {
         /* Retain the SID for the old missing glyph ID */
         old_glyph = glyph;
       }
-      sid = glyph_to_sid_map ? glyph_to_sid_map->get (old_glyph) : acc.glyph_to_sid (old_glyph);
+      unsigned sid = glyph_to_sid_map ?
+                     glyph_to_sid_map->arrayZ[old_glyph].code :
+                     acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache);
 
-      if (!acc.is_CID ())
+      if (not_is_cid)
         sid = sidmap.add (sid);
 
-      if ((last_sid == CFF_UNDEF_CODE) || (sid != last_sid + 1))
+      if (sid != last_sid + 1)
+        subset_charset_ranges.push (code_pair_t {sid, glyph});
+
+      if (glyph == old_glyph && skip)
       {
-        code_pair_t pair = { sid, glyph };
-        subset_charset_ranges.push (pair);
+        glyph = hb_min (_.first - 1, glyph_to_sid_map->arrayZ[old_glyph].glyph);
+        sid += glyph - old_glyph;
       }
       last_sid = sid;
     }
 
     if (created_map)
     {
-      if (!(plan->accelerator && plan->accelerator->cff_accelerator) ||
-          !plan->accelerator->cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map))
-        hb_map_destroy (glyph_to_sid_map);
+      if ((!plan->accelerator && acc.cff_accelerator) ||
+          !acc.cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map))
+      {
+        glyph_to_sid_map->~glyph_to_sid_map_t ();
+        hb_free (glyph_to_sid_map);
+      }
     }
 
-    bool two_byte = subset_charset_ranges.complete (glyph);
+    bool two_byte = subset_charset_ranges.complete (num_glyphs);
 
-    size0 = Charset0::min_size + HBUINT16::static_size * (plan->num_output_glyphs () - 1);
+    size0 = Charset0::get_size (plan->num_output_glyphs ());
     if (!two_byte)
-      size_ranges = Charset1::min_size + Charset1_Range::static_size * subset_charset_ranges.length;
+      size_ranges = Charset1::get_size_for_ranges (subset_charset_ranges.length);
     else
-      size_ranges = Charset2::min_size + Charset2_Range::static_size * subset_charset_ranges.length;
+      size_ranges = Charset2::get_size_for_ranges (subset_charset_ranges.length);
 
     if (size0 < size_ranges)
       subset_charset_format = 0;
@@ -528,19 +585,18 @@
       subset_charset_format = 1;
     else
       subset_charset_format = 2;
+
+    return true;
   }
 
   bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
   {
-    sidmap.reset ();
-
     for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
     {
       unsigned int sid = acc.topDict.nameSIDs[i];
       if (sid != CFF_UNDEF_SID)
       {
-        (void)sidmap.add (sid);
-        topDictModSIDs[i] = sidmap[sid];
+        topDictModSIDs[i] = sidmap.add (sid);
       }
     }
 
@@ -564,19 +620,18 @@
     drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
     desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE;
 
-    /* check whether the subset renumbers any glyph IDs */
-    gid_renum = false;
-    for (hb_codepoint_t new_glyph = 0; new_glyph < plan->num_output_glyphs (); new_glyph++)
-    {
-      if (!plan->old_gid_for_new_gid(new_glyph, &old_glyph))
-        continue;
-      if (new_glyph != old_glyph) {
-        gid_renum = true;
-        break;
+    subset_charset = !acc.is_predef_charset ();
+    if (!subset_charset)
+      /* check whether the subset renumbers any glyph IDs */
+      for (const auto &_ : plan->new_to_old_gid_list)
+      {
+        if (_.first != _.second)
+        {
+          subset_charset = true;
+          break;
+        }
       }
-    }
 
-    subset_charset = gid_renum || !acc.is_predef_charset ();
     subset_encoding = !acc.is_CID() && !acc.is_predef_encoding ();
 
     /* top dict INDEX */
@@ -618,7 +673,8 @@
       if (unlikely (sidmap.get_population () > 0x8000)) /* assumption: a dict won't reference that many strings */
         return false;
 
-      if (subset_charset) plan_subset_charset (acc, plan);
+      if (subset_charset && !plan_subset_charset (acc, plan))
+        return false;
 
       topdict_mod.reassignSIDs (sidmap);
     }
@@ -682,8 +738,9 @@
       ;
     }
 
-    return ((subset_charstrings.length == plan->num_output_glyphs ())
-           && (fontdicts_mod.length == subset_fdcount));
+    return !plan->in_error () &&
+           (subset_charstrings.length == plan->num_output_glyphs ()) &&
+           (fontdicts_mod.length == subset_fdcount);
   }
 
   cff1_top_dict_values_mod_t    topdict_mod;
@@ -722,24 +779,22 @@
 
   bool          desubroutinize = false;
 };
+} // namespace OT
 
-static bool _serialize_cff1 (hb_serialize_context_t *c,
-                             cff_subset_plan &plan,
-                             const OT::cff1::accelerator_subset_t  &acc,
-                             unsigned int num_glyphs)
+bool
+OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c,
+                                           struct OT::cff1_subset_plan &plan) const
 {
   /* private dicts & local subrs */
-  for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
+  for (int i = (int) privateDicts.length; --i >= 0 ;)
   {
     if (plan.fdmap.has (i))
     {
       objidx_t  subrs_link = 0;
       if (plan.subset_localsubrs[i].length > 0)
       {
-        CFF1Subrs *dest = c->start_embed  ();
-        if (unlikely (!dest)) return false;
-        c->push ();
-        if (likely (dest && dest->serialize (c, plan.subset_localsubrs[i])))
+        auto *dest = c->push  ();
+        if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
           subrs_link = c->pop_pack ();
         else
         {
@@ -748,12 +803,10 @@
         }
       }
 
-      PrivateDict *pd = c->start_embed ();
-      if (unlikely (!pd)) return false;
-      c->push ();
+      auto *pd = c->push ();
       cff1_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
       /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
+      if (likely (pd->serialize (c, privateDicts[i], privSzr, subrs_link)))
       {
         unsigned fd = plan.fdmap[i];
         plan.fontdicts_mod[fd].privateDictInfo.size = c->length ();
@@ -767,21 +820,20 @@
     }
   }
 
-  if (!acc.is_CID ())
+  if (!is_CID ())
     plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo;
 
   /* CharStrings */
   {
     c->push ();
 
-    unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings);
+    unsigned data_size = 0;
+    unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size);
     if (unlikely (!c->start_zerocopy (total_size)))
        return false;
 
-    CFF1CharStrings  *cs = c->start_embed ();
-    if (unlikely (!cs)) return false;
-
-    if (likely (cs->serialize (c, plan.subset_charstrings)))
+    auto *cs = c->start_embed ();
+    if (likely (cs->serialize (c, plan.subset_charstrings, &data_size)))
       plan.info.char_strings_link = c->pop_pack (false);
     else
     {
@@ -791,11 +843,9 @@
   }
 
   /* FDArray (FD Index) */
-  if (acc.fdArray != &Null (CFF1FDArray))
+  if (fdArray != &Null (CFF1FDArray))
   {
-    CFF1FDArray *fda = c->start_embed ();
-    if (unlikely (!fda)) return false;
-    c->push ();
+    auto *fda = c->push ();
     cff1_font_dict_op_serializer_t  fontSzr;
     auto it = + hb_zip (+ hb_iter (plan.fontdicts_mod), + hb_iter (plan.fontdicts_mod));
     if (likely (fda->serialize (c, it, fontSzr)))
@@ -808,10 +858,10 @@
   }
 
   /* FDSelect */
-  if (acc.fdSelect != &Null (CFF1FDSelect))
+  if (fdSelect != &Null (CFF1FDSelect))
   {
     c->push ();
-    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *acc.fdSelect, acc.fdCount,
+    if (likely (hb_serialize_cff_fdselect (c, plan.num_glyphs, *fdSelect, fdCount,
                                            plan.subset_fdselect_format, plan.info.fd_select.size,
                                            plan.subset_fdselect_ranges)))
       plan.info.fd_select.link = c->pop_pack ();
@@ -825,9 +875,7 @@
   /* Charset */
   if (plan.subset_charset)
   {
-    Charset *dest = c->start_embed ();
-    if (unlikely (!dest)) return false;
-    c->push ();
+    auto *dest = c->push ();
     if (likely (dest->serialize (c,
                                  plan.subset_charset_format,
                                  plan.num_glyphs,
@@ -843,9 +891,7 @@
   /* Encoding */
   if (plan.subset_encoding)
   {
-    Encoding *dest = c->start_embed ();
-    if (unlikely (!dest)) return false;
-    c->push ();
+    auto *dest = c->push ();
     if (likely (dest->serialize (c,
                                  plan.subset_enc_format,
                                  plan.subset_enc_num_codes,
@@ -861,9 +907,7 @@
 
   /* global subrs */
   {
-    c->push ();
-    CFF1Subrs *dest = c->start_embed  ();
-    if (unlikely (!dest)) return false;
+    auto *dest = c->push  ();
     if (likely (dest->serialize (c, plan.subset_globalsubrs)))
       c->pop_pack (false);
     else
@@ -875,10 +919,9 @@
 
   /* String INDEX */
   {
-    CFF1StringIndex *dest = c->start_embed ();
-    if (unlikely (!dest)) return false;
-    c->push ();
-    if (likely (dest->serialize (c, *acc.stringIndex, plan.sidmap)))
+    auto *dest = c->push ();
+    if (likely (!plan.sidmap.in_error () &&
+                dest->serialize (c, *stringIndex, plan.sidmap.vector)))
       c->pop_pack ();
     else
     {
@@ -898,14 +941,12 @@
   cff->offSize = 4; /* unused? */
 
   /* name INDEX */
-  if (unlikely (!(*acc.nameIndex).copy (c))) return false;
+  if (unlikely (!c->embed (*nameIndex))) return false;
 
   /* top dict INDEX */
   {
     /* serialize singleton TopDict */
-    TopDict *top = c->start_embed ();
-    if (!top) return false;
-    c->push ();
+    auto *top = c->push ();
     cff1_top_dict_op_serializer_t topSzr;
     unsigned top_size = 0;
     top_dict_modifiers_t  modifier (plan.info, plan.topDictModSIDs);
@@ -920,36 +961,23 @@
       return false;
     }
     /* serialize INDEX header for above */
-    CFF1Index *dest = c->start_embed ();
-    if (!dest) return false;
-    return dest->serialize_header (c, hb_iter (hb_array_t (&top_size, 1)));
+    auto *dest = c->start_embed ();
+    return dest->serialize_header (c, hb_iter (&top_size, 1), top_size);
   }
 }
 
-static bool
-_hb_subset_cff1 (const OT::cff1::accelerator_subset_t  &acc,
-                hb_subset_context_t     *c)
+bool
+OT::cff1::accelerator_subset_t::subset (hb_subset_context_t *c) const
 {
-  cff_subset_plan cff_plan;
+  cff1_subset_plan cff_plan;
 
-  if (unlikely (!cff_plan.create (acc, c->plan)))
+  if (unlikely (!cff_plan.create (*this, c->plan)))
   {
     DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff subsetting plan.");
     return false;
   }
 
-  return _serialize_cff1 (c->serializer, cff_plan, acc, c->plan->num_output_glyphs ());
-}
-
-bool
-hb_subset_cff1 (hb_subset_context_t *c)
-{
-  OT::cff1::accelerator_subset_t acc;
-  acc.init (c->plan->source);
-  bool result = likely (acc.is_valid ()) && _hb_subset_cff1 (acc, c);
-  acc.fini ();
-
-  return result;
+  return serialize (c->serializer, cff_plan);
 }
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.hh	1970-01-01 00:00:00.000000000 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF1_HH
-#define HB_SUBSET_CFF1_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff1 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF1_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc	2024-01-16 16:19:00.000000000 +0000
@@ -31,7 +31,6 @@
 #include "hb-open-type.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-set.h"
-#include "hb-subset-cff2.hh"
 #include "hb-subset-plan.hh"
 #include "hb-subset-cff-common.hh"
 #include "hb-cff2-interp-cs.hh"
@@ -422,11 +421,17 @@
 };
 
 
+namespace OT {
 struct cff2_subset_plan
 {
   bool create (const OT::cff2::accelerator_subset_t &acc,
               hb_subset_plan_t *plan)
   {
+    /* make sure notdef is first */
+    hb_codepoint_t old_glyph;
+    if (!plan->old_gid_for_new_gid (0, &old_glyph) || (old_glyph != 0)) return false;
+
+    num_glyphs = plan->num_output_glyphs ();
     orig_fdcount = acc.fdArray->count;
 
     drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
@@ -489,6 +494,7 @@
 
   cff2_sub_table_info_t info;
 
+  unsigned int    num_glyphs;
   unsigned int    orig_fdcount = 0;
   unsigned int    subset_fdcount = 1;
   unsigned int    subset_fdselect_size = 0;
@@ -505,18 +511,18 @@
   bool      drop_hints = false;
   bool      desubroutinize = false;
 };
+} // namespace OT
 
-static bool _serialize_cff2 (hb_serialize_context_t *c,
-                             cff2_subset_plan &plan,
-                             const OT::cff2::accelerator_subset_t  &acc,
-                             unsigned int num_glyphs,
-                             hb_array_t normalized_coords)
+bool
+OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c,
+                                           struct cff2_subset_plan &plan,
+                                           hb_array_t normalized_coords) const
 {
   /* private dicts & local subrs */
   hb_vector_t  private_dict_infos;
   if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false;
 
-  for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
+  for (int i = (int)privateDicts.length; --i >= 0 ;)
   {
     if (plan.fdmap.has (i))
     {
@@ -524,9 +530,7 @@
 
       if (plan.subset_localsubrs[i].length > 0)
       {
-        CFF2Subrs *dest = c->start_embed  ();
-        if (unlikely (!dest)) return false;
-        c->push ();
+        auto *dest = c->push  ();
         if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
           subrs_link = c->pop_pack (false);
         else
@@ -535,12 +539,10 @@
           return false;
         }
       }
-      PrivateDict *pd = c->start_embed ();
-      if (unlikely (!pd)) return false;
-      c->push ();
+      auto *pd = c->push ();
       cff2_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints, plan.pinned,
-                                                 acc.varStore, normalized_coords);
-      if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
+                                                 varStore, normalized_coords);
+      if (likely (pd->serialize (c, privateDicts[i], privSzr, subrs_link)))
       {
         unsigned fd = plan.fdmap[i];
         private_dict_infos[fd].size = c->length ();
@@ -558,14 +560,13 @@
   {
     c->push ();
 
-    unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings);
+    unsigned data_size = 0;
+    unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size);
     if (unlikely (!c->start_zerocopy (total_size)))
        return false;
 
-    CFF2CharStrings  *cs = c->start_embed ();
-    if (unlikely (!cs)) return false;
-
-    if (likely (cs->serialize (c, plan.subset_charstrings)))
+    auto *cs = c->start_embed ();
+    if (likely (cs->serialize (c, plan.subset_charstrings, &data_size)))
       plan.info.char_strings_link = c->pop_pack (false);
     else
     {
@@ -575,10 +576,10 @@
   }
 
   /* FDSelect */
-  if (acc.fdSelect != &Null (CFF2FDSelect))
+  if (fdSelect != &Null (CFF2FDSelect))
   {
     c->push ();
-    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect,
+    if (likely (hb_serialize_cff_fdselect (c, plan.num_glyphs, *(const FDSelect *)fdSelect,
                                            plan.orig_fdcount,
                                            plan.subset_fdselect_format, plan.subset_fdselect_size,
                                            plan.subset_fdselect_ranges)))
@@ -592,27 +593,32 @@
 
   /* FDArray (FD Index) */
   {
-    c->push ();
-    CFF2FDArray *fda = c->start_embed ();
-    if (unlikely (!fda)) return false;
+    auto *fda = c->push ();
     cff_font_dict_op_serializer_t fontSzr;
     auto it =
-    + hb_zip (+ hb_iter (acc.fontDicts)
+    + hb_zip (+ hb_iter (fontDicts)
               | hb_filter ([&] (const cff2_font_dict_values_t &_)
-                { return plan.fdmap.has (&_ - &acc.fontDicts[0]); }),
+                { return plan.fdmap.has (&_ - &fontDicts[0]); }),
               hb_iter (private_dict_infos))
     ;
-    if (unlikely (!fda->serialize (c, it, fontSzr))) return false;
+    if (unlikely (!fda->serialize (c, it, fontSzr)))
+    {
+      c->pop_discard ();
+      return false;
+    }
     plan.info.fd_array_link = c->pop_pack (false);
   }
 
   /* variation store */
-  if (acc.varStore != &Null (CFF2VariationStore) &&
+  if (varStore != &Null (CFF2VariationStore) &&
       !plan.pinned)
   {
-    c->push ();
-    CFF2VariationStore *dest = c->start_embed ();
-    if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false;
+    auto *dest = c->push ();
+    if (unlikely (!dest->serialize (c, varStore)))
+    {
+      c->pop_discard ();
+      return false;
+    }
     plan.info.var_store_link = c->pop_pack (false);
   }
 
@@ -628,34 +634,25 @@
   {
     TopDict &dict = cff2 + cff2->topDict;
     cff2_top_dict_op_serializer_t topSzr;
-    if (unlikely (!dict.serialize (c, acc.topDict, topSzr, plan.info))) return false;
+    if (unlikely (!dict.serialize (c, topDict, topSzr, plan.info))) return false;
     cff2->topDictSize = c->head - (const char *)&dict;
   }
 
   /* global subrs */
   {
-    CFF2Subrs *dest = c->start_embed  ();
-    if (unlikely (!dest)) return false;
+    auto *dest = c->start_embed  ();
     return dest->serialize (c, plan.subset_globalsubrs);
   }
 }
 
-static bool
-_hb_subset_cff2 (const OT::cff2::accelerator_subset_t  &acc,
-                 hb_subset_context_t    *c)
+bool
+OT::cff2::accelerator_subset_t::subset (hb_subset_context_t *c) const
 {
   cff2_subset_plan cff2_plan;
 
-  if (unlikely (!cff2_plan.create (acc, c->plan))) return false;
-  return _serialize_cff2 (c->serializer, cff2_plan, acc, c->plan->num_output_glyphs (),
-                          c->plan->normalized_coords.as_array ());
-}
-
-bool
-hb_subset_cff2 (hb_subset_context_t *c)
-{
-  OT::cff2::accelerator_subset_t acc (c->plan->source);
-  return acc.is_valid () && _hb_subset_cff2 (acc, c);
+  if (unlikely (!cff2_plan.create (*this, c->plan))) return false;
+  return serialize (c->serializer, cff2_plan,
+                    c->plan->normalized_coords.as_array ());
 }
 
 #endif
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.hh	1970-01-01 00:00:00.000000000 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF2_HH
-#define HB_SUBSET_CFF2_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff2 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF2_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc	2024-01-16 16:19:00.000000000 +0000
@@ -69,14 +69,11 @@
   sets.drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
 
   hb_tag_t default_no_subset_tables[] = {
-    HB_TAG ('a', 'v', 'a', 'r'),
     HB_TAG ('g', 'a', 's', 'p'),
     HB_TAG ('f', 'p', 'g', 'm'),
     HB_TAG ('p', 'r', 'e', 'p'),
     HB_TAG ('V', 'D', 'M', 'X'),
     HB_TAG ('D', 'S', 'I', 'G'),
-    HB_TAG ('M', 'V', 'A', 'R'),
-    HB_TAG ('c', 'v', 'a', 'r'),
   };
   sets.no_subset_tables->add_array (default_no_subset_tables,
                                          ARRAY_LENGTH (default_no_subset_tables));
@@ -438,7 +435,8 @@
   if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
     return false;
 
-  return input->axes_location.set (axis_tag, axis_info.default_value);
+  float default_val = axis_info.default_value;
+  return input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val));
 }
 
 /**
@@ -468,8 +466,59 @@
     return false;
 
   float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value);
-  return input->axes_location.set (axis_tag, val);
+  return input->axes_location.set (axis_tag, Triple (val, val, val));
 }
+
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_subset_input_set_axis_range: (skip)
+ * @input: a #hb_subset_input_t object.
+ * @face: a #hb_face_t object.
+ * @axis_tag: Tag of the axis
+ * @axis_min_value: Minimum value of the axis variation range to set
+ * @axis_max_value: Maximum value of the axis variation range to set
+ * @axis_def_value: Default value of the axis variation range to set, in case of
+ * null, it'll be determined automatically
+ *
+ * Restricting the range of variation on an axis in the given subset input object.
+ * New min/default/max values will be clamped if they're not within the fvar axis range.
+ * If the new default value is null:
+ * If the fvar axis default value is within the new range, then new default
+ * value is the same as original default value.
+ * If the fvar axis default value is not within the new range, the new default
+ * value will be changed to the new min or max value, whichever is closer to the fvar
+ * axis default.
+ *
+ * Note: input min value can not be bigger than input max value. If the input
+ * default value is not within the new min/max range, it'll be clamped.
+ * Note: currently it supports gvar and cvar tables only.
+ *
+ * Return value: `true` if success, `false` otherwise
+ *
+ * XSince: EXPERIMENTAL
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_set_axis_range (hb_subset_input_t  *input,
+                                hb_face_t          *face,
+                                hb_tag_t            axis_tag,
+                                float               axis_min_value,
+                                float               axis_max_value,
+                                float              *axis_def_value /* IN, maybe NULL */)
+{
+  if (axis_min_value > axis_max_value)
+    return false;
+
+  hb_ot_var_axis_info_t axis_info;
+  if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
+    return false;
+
+  float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value);
+  float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value);
+  float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value;
+  new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val);
+  return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val));
+}
+#endif
 #endif
 
 /**
@@ -520,6 +569,37 @@
   return new_source;
 }
 
+/**
+ * hb_subset_input_old_to_new_glyph_mapping:
+ * @input: a #hb_subset_input_t object.
+ *
+ * Returns a map which can be used to provide an explicit mapping from old to new glyph
+ * id's in the produced subset. The caller should populate the map as desired.
+ * If this map is left empty then glyph ids will be automatically mapped to new
+ * values by the subsetter. If populated, the mapping must be unique. That
+ * is no two original glyph ids can be mapped to the same new id.
+ * Additionally, if a mapping is provided then the retain gids option cannot
+ * be enabled.
+ *
+ * Any glyphs that are retained in the subset which are not specified
+ * in this mapping will be assigned glyph ids after the highest glyph
+ * id in the mapping.
+ *
+ * Note: this will accept and apply non-monotonic mappings, however this
+ * may result in unsorted Coverage tables. Such fonts may not work for all
+ * use cases (for example ots will reject unsorted coverage tables). So it's
+ * recommended, if possible, to supply a monotonic mapping.
+ *
+ * Return value: (transfer none): pointer to the #hb_map_t of the custom glyphs ID map.
+ *
+ * Since: 7.3.0
+ **/
+HB_EXTERN hb_map_t*
+hb_subset_input_old_to_new_glyph_mapping (hb_subset_input_t *input)
+{
+  return &input->glyph_map;
+}
+
 #ifdef HB_EXPERIMENTAL_API
 /**
  * hb_subset_input_override_name_table:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh	2024-01-16 16:19:00.000000000 +0000
@@ -35,6 +35,7 @@
 #include "hb-set.hh"
 #include "hb-cplusplus.hh"
 #include "hb-font.hh"
+#include "hb-subset-instancer-solver.hh"
 
 struct hb_ot_name_record_ids_t
 {
@@ -118,7 +119,8 @@
   // If set loca format will always be the long version.
   bool force_long_loca = false;
 
-  hb_hashmap_t axes_location;
+  hb_hashmap_t axes_location;
+  hb_map_t glyph_map;
 #ifdef HB_EXPERIMENTAL_API
   hb_hashmap_t name_table_overrides;
 #endif
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,429 @@
+/*
+ * Copyright © 2023  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb-subset-instancer-solver.hh"
+
+/* This file is a straight port of the following:
+ *
+ * https://github.com/fonttools/fonttools/blob/f73220816264fc383b8a75f2146e8d69e455d398/Lib/fontTools/varLib/instancer/solver.py
+ *
+ * Where that file returns None for a triple, we return Triple{}.
+ * This should be safe.
+ */
+
+constexpr static float EPSILON = 1.f / (1 << 14);
+constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14);
+
+static inline Triple _reverse_negate(const Triple &v)
+{ return {-v.maximum, -v.middle, -v.minimum}; }
+
+
+static inline float supportScalar (float coord, const Triple &tent)
+{
+  /* Copied from VarRegionAxis::evaluate() */
+  float start = tent.minimum, peak = tent.middle, end = tent.maximum;
+
+  if (unlikely (start > peak || peak > end))
+    return 1.;
+  if (unlikely (start < 0 && end > 0 && peak != 0))
+    return 1.;
+
+  if (peak == 0 || coord == peak)
+    return 1.;
+
+  if (coord <= start || end <= coord)
+    return 0.;
+
+  /* Interpolate */
+  if (coord < peak)
+    return (coord - start) / (peak - start);
+  else
+    return  (end - coord) / (end - peak);
+}
+
+static inline result_t
+_solve (Triple tent, Triple axisLimit, bool negative = false)
+{
+  float axisMin = axisLimit.minimum;
+  float axisDef = axisLimit.middle;
+  float axisMax = axisLimit.maximum;
+  float lower = tent.minimum;
+  float peak  = tent.middle;
+  float upper = tent.maximum;
+
+  // Mirror the problem such that axisDef <= peak
+  if (axisDef > peak)
+  {
+    result_t vec = _solve (_reverse_negate (tent),
+                           _reverse_negate (axisLimit),
+                           !negative);
+
+    for (auto &p : vec)
+      p = hb_pair (p.first, _reverse_negate (p.second));
+
+    return vec;
+  }
+  // axisDef <= peak
+
+  /* case 1: The whole deltaset falls outside the new limit; we can drop it
+   *
+   *                                          peak
+   *  1.........................................o..........
+   *                                           / \
+   *                                          /   \
+   *                                         /     \
+   *                                        /       \
+   *  0---|-----------|----------|-------- o         o----1
+   *    axisMin     axisDef    axisMax   lower     upper
+   */
+  if (axisMax <= lower && axisMax < peak)
+      return result_t{};  // No overlap
+
+  /* case 2: Only the peak and outermost bound fall outside the new limit;
+   * we keep the deltaset, update peak and outermost bound and scale deltas
+   * by the scalar value for the restricted axis at the new limit, and solve
+   * recursively.
+   *
+   *                                  |peak
+   *  1...............................|.o..........
+   *                                  |/ \
+   *                                  /   \
+   *                                 /|    \
+   *                                / |     \
+   *  0--------------------------- o  |      o----1
+   *                           lower  |      upper
+   *                                  |
+   *                                axisMax
+   *
+   * Convert to:
+   *
+   *  1............................................
+   *                                  |
+   *                                  o peak
+   *                                 /|
+   *                                /x|
+   *  0--------------------------- o  o upper ----1
+   *                           lower  |
+   *                                  |
+   *                                axisMax
+   */
+  if (axisMax < peak)
+  {
+    float mult = supportScalar (axisMax, tent);
+    tent = Triple{lower, axisMax, axisMax};
+
+    result_t vec = _solve (tent, axisLimit);
+
+    for (auto &p : vec)
+      p = hb_pair (p.first * mult, p.second);
+
+    return vec;
+  }
+
+  // lower <= axisDef <= peak <= axisMax
+
+  float gain = supportScalar (axisDef, tent);
+  result_t out {hb_pair (gain, Triple{})};
+
+  // First, the positive side
+
+  // outGain is the scalar of axisMax at the tent.
+  float outGain = supportScalar (axisMax, tent);
+
+  /* Case 3a: Gain is more than outGain. The tent down-slope crosses
+   * the axis into negative. We have to split it into multiples.
+   *
+   *                      | peak  |
+   *  1...................|.o.....|..............
+   *                      |/x\_   |
+   *  gain................+....+_.|..............
+   *                     /|    |y\|
+   *  ................../.|....|..+_......outGain
+   *                   /  |    |  | \
+   *  0---|-----------o   |    |  |  o----------1
+   *    axisMin    lower  |    |  |   upper
+   *                      |    |  |
+   *                axisDef    |  axisMax
+   *                           |
+   *                      crossing
+   */
+  if (gain > outGain)
+  {
+    // Crossing point on the axis.
+    float crossing = peak + (1 - gain) * (upper - peak);
+
+    Triple loc{axisDef, peak, crossing};
+    float scalar = 1.f;
+
+    // The part before the crossing point.
+    out.push (hb_pair (scalar - gain, loc));
+
+    /* The part after the crossing point may use one or two tents,
+     * depending on whether upper is before axisMax or not, in one
+     * case we need to keep it down to eternity.
+     *
+     * Case 3a1, similar to case 1neg; just one tent needed, as in
+     * the drawing above.
+     */
+    if (upper >= axisMax)
+    {
+      Triple loc {crossing, axisMax, axisMax};
+      float scalar = outGain;
+
+      out.push (hb_pair (scalar - gain, loc));
+    }
+
+    /* Case 3a2: Similar to case 2neg; two tents needed, to keep
+     * down to eternity.
+     *
+     *                      | peak             |
+     *  1...................|.o................|...
+     *                      |/ \_              |
+     *  gain................+....+_............|...
+     *                     /|    | \xxxxxxxxxxy|
+     *                    / |    |  \_xxxxxyyyy|
+     *                   /  |    |    \xxyyyyyy|
+     *  0---|-----------o   |    |     o-------|--1
+     *    axisMin    lower  |    |      upper  |
+     *                      |    |             |
+     *                axisDef    |             axisMax
+     *                           |
+     *                      crossing
+     */
+    else
+    {
+      // A tent's peak cannot fall on axis default. Nudge it.
+      if (upper == axisDef)
+        upper += EPSILON;
+
+      // Downslope.
+      Triple loc1 {crossing, upper, axisMax};
+      float scalar1 = 0.f;
+
+      // Eternity justify.
+      Triple loc2 {upper, axisMax, axisMax};
+      float scalar2 = 0.f;
+
+      out.push (hb_pair (scalar1 - gain, loc1));
+      out.push (hb_pair (scalar2 - gain, loc2));
+    }
+  }
+
+  else
+  {
+    // Special-case if peak is at axisMax.
+    if (axisMax == peak)
+        upper = peak;
+
+    /* Case 3:
+     * we keep deltas as is and only scale the axis upper to achieve
+     * the desired new tent if feasible.
+     *
+     *                        peak
+     *  1.....................o....................
+     *                       / \_|
+     *  ..................../....+_.........outGain
+     *                     /     | \
+     *  gain..............+......|..+_.............
+     *                   /|      |  | \
+     *  0---|-----------o |      |  |  o----------1
+     *    axisMin    lower|      |  |   upper
+     *                    |      |  newUpper
+     *              axisDef      axisMax
+     */
+    float newUpper = peak + (1 - gain) * (upper - peak);
+    assert (axisMax <= newUpper);  // Because outGain >= gain
+    if (newUpper <= axisDef + (axisMax - axisDef) * 2)
+    {
+      upper = newUpper;
+      if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper)
+      {
+        // we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
+        upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14;
+        assert (peak < upper);
+      }
+
+      Triple loc {hb_max (axisDef, lower), peak, upper};
+      float scalar = 1.f;
+
+      out.push (hb_pair (scalar - gain, loc));
+    }
+
+    /* Case 4: New limit doesn't fit; we need to chop into two tents,
+     * because the shape of a triangle with part of one side cut off
+     * cannot be represented as a triangle itself.
+     *
+     *            |   peak |
+     *  1.........|......o.|....................
+     *  ..........|...../x\|.............outGain
+     *            |    |xxy|\_
+     *            |   /xxxy|  \_
+     *            |  |xxxxy|    \_
+     *            |  /xxxxy|      \_
+     *  0---|-----|-oxxxxxx|        o----------1
+     *    axisMin | lower  |        upper
+     *            |        |
+     *          axisDef  axisMax
+     */
+    else
+    {
+      Triple loc1 {hb_max (axisDef, lower), peak, axisMax};
+      float scalar1 = 1.f;
+
+      Triple loc2 {peak, axisMax, axisMax};
+      float scalar2 = outGain;
+
+      out.push (hb_pair (scalar1 - gain, loc1));
+      // Don't add a dirac delta!
+      if (peak < axisMax)
+        out.push (hb_pair (scalar2 - gain, loc2));
+    }
+  }
+
+  /* Now, the negative side
+   *
+   * Case 1neg: Lower extends beyond axisMin: we chop. Simple.
+   *
+   *                     |   |peak
+   *  1..................|...|.o.................
+   *                     |   |/ \
+   *  gain...............|...+...\...............
+   *                     |x_/|    \
+   *                     |/  |     \
+   *                   _/|   |      \
+   *  0---------------o  |   |       o----------1
+   *              lower  |   |       upper
+   *                     |   |
+   *               axisMin   axisDef
+   */
+  if (lower <= axisMin)
+  {
+    Triple loc {axisMin, axisMin, axisDef};
+    float scalar = supportScalar (axisMin, tent);
+
+    out.push (hb_pair (scalar - gain, loc));
+  }
+
+  /* Case 2neg: Lower is betwen axisMin and axisDef: we add two
+   * tents to keep it down all the way to eternity.
+   *
+   *      |               |peak
+   *  1...|...............|.o.................
+   *      |               |/ \
+   *  gain|...............+...\...............
+   *      |yxxxxxxxxxxxxx/|    \
+   *      |yyyyyyxxxxxxx/ |     \
+   *      |yyyyyyyyyyyx/  |      \
+   *  0---|-----------o   |       o----------1
+   *    axisMin    lower  |       upper
+   *                      |
+   *                    axisDef
+   */
+  else
+  {
+    // A tent's peak cannot fall on axis default. Nudge it.
+    if (lower == axisDef)
+      lower -= EPSILON;
+
+    // Downslope.
+    Triple loc1 {axisMin, lower, axisDef};
+    float scalar1 = 0.f;
+
+    // Eternity justify.
+    Triple loc2 {axisMin, axisMin, lower};
+    float scalar2 = 0.f;
+
+    out.push (hb_pair (scalar1 - gain, loc1));
+    out.push (hb_pair (scalar2 - gain, loc2));
+  }
+
+  return out;
+}
+
+static inline TripleDistances _reverse_triple_distances (const TripleDistances &v)
+{ return TripleDistances (v.positive, v.negative); }
+
+float renormalizeValue (float v, const Triple &triple,
+                        const TripleDistances &triple_distances, bool extrapolate)
+{
+  float lower = triple.minimum, def = triple.middle, upper = triple.maximum;
+  assert (lower <= def && def <= upper);
+
+  if (!extrapolate)
+      v = hb_max (hb_min (v, upper), lower);
+
+  if (v == def)
+    return 0.f;
+
+  if (def < 0.f)
+    return -renormalizeValue (-v, _reverse_negate (triple),
+                              _reverse_triple_distances (triple_distances), extrapolate);
+
+  /* default >= 0 and v != default */
+  if (v > def)
+    return (v - def) / (upper - def);
+
+  /* v < def */
+  if (lower >= 0.f)
+    return (v - def) / (def - lower);
+
+  /* lower < 0 and v < default */
+  float total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def;
+
+  float v_distance;
+  if (v >= 0.f)
+    v_distance = (def - v) * triple_distances.positive;
+  else
+    v_distance = (-v) * triple_distances.negative + triple_distances.positive * def;
+
+  return (-v_distance) /total_distance;
+}
+
+result_t
+rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances)
+{
+  assert (-1.f <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.f);
+  assert (-2.f <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.f);
+  assert (tent.middle != 0.f);
+
+  result_t sols = _solve (tent, axisLimit);
+
+  auto n = [&axisLimit, &axis_triple_distances] (float v) { return renormalizeValue (v, axisLimit, axis_triple_distances); };
+
+  result_t out;
+  for (auto &p : sols)
+  {
+    if (!p.first) continue;
+    if (p.second == Triple{})
+    {
+      out.push (p);
+      continue;
+    }
+    Triple t = p.second;
+    out.push (hb_pair (p.first,
+                       Triple{n (t.minimum), n (t.middle), n (t.maximum)}));
+  }
+
+  return out;
+}
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2023  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_SUBSET_INSTANCER_SOLVER_HH
+#define HB_SUBSET_INSTANCER_SOLVER_HH
+
+#include "hb.hh"
+
+/* pre-normalized distances */
+struct TripleDistances
+{
+  TripleDistances (): negative (1.f), positive (1.f) {}
+  TripleDistances (float neg_, float pos_): negative (neg_), positive (pos_) {}
+  TripleDistances (float min, float default_, float max)
+  {
+    negative = default_ - min;
+    positive = max - default_;
+  }
+
+  float negative;
+  float positive;
+};
+
+struct Triple {
+
+  Triple () :
+    minimum (0.f), middle (0.f), maximum (0.f) {}
+
+  Triple (float minimum_, float middle_, float maximum_) :
+    minimum (minimum_), middle (middle_), maximum (maximum_) {}
+
+  bool operator == (const Triple &o) const
+  {
+    return minimum == o.minimum &&
+           middle  == o.middle  &&
+           maximum == o.maximum;
+  }
+
+  bool operator != (const Triple o) const
+  { return !(*this == o); }
+
+  bool is_point () const
+  { return minimum == middle && middle == maximum; }
+
+  bool contains (float point) const
+  { return minimum <= point && point <= maximum; }
+
+  /* from hb_array_t hash ()*/
+  uint32_t hash () const
+  {
+    uint32_t current = /*cbf29ce4*/0x84222325;
+    current = current ^ hb_hash (minimum);
+    current = current * 16777619;
+
+    current = current ^ hb_hash (middle);
+    current = current * 16777619;
+
+    current = current ^ hb_hash (maximum);
+    current = current * 16777619;
+    return current;
+  }
+
+
+  float minimum;
+  float middle;
+  float maximum;
+};
+
+using result_item_t = hb_pair_t;
+using result_t = hb_vector_t;
+
+/* renormalize a normalized value v to the range of an axis,
+ * considering the prenormalized distances as well as the new axis limits.
+ * Ported from fonttools */
+HB_INTERNAL float renormalizeValue (float v, const Triple &triple,
+                                    const TripleDistances &triple_distances,
+                                    bool extrapolate = true);
+/* Given a tuple (lower,peak,upper) "tent" and new axis limits
+ * (axisMin,axisDefault,axisMax), solves how to represent the tent
+ * under the new axis configuration.  All values are in normalized
+ * -1,0,+1 coordinate system. Tent values can be outside this range.
+ *
+ * Return value: a list of tuples. Each tuple is of the form
+ * (scalar,tent), where scalar is a multipler to multiply any
+ * delta-sets by, and tent is a new tent for that output delta-set.
+ * If tent value is Triple{}, that is a special deltaset that should
+ * be always-enabled (called "gain").
+ */
+HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances);
+
+#endif /* HB_SUBSET_INSTANCER_SOLVER_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ * Copyright © 2023  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger, Roderick Sheeter
+ */
+
+#ifndef HB_SUBSET_PLAN_MEMBER_LIST_HH
+#define HB_SUBSET_PLAN_MEMBER_LIST_HH
+#endif /* HB_SUBSET_PLAN_MEMBER_LIST_HH */ /* Dummy header guards */
+
+#define E(x, y) x, y
+
+// For each cp that we'd like to retain maps to the corresponding gid.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, unicodes)
+HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t, unicode_to_new_gid_list)
+
+HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t, new_to_old_gid_list)
+
+// name_ids we would like to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, name_ids)
+
+// name_languages we would like to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, name_languages)
+
+//layout features which will be preserved
+HB_SUBSET_PLAN_MEMBER (hb_set_t, layout_features)
+
+// layout scripts which will be preserved.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, layout_scripts)
+
+//glyph ids requested to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, glyphs_requested)
+
+// Tables which should not be processed, just pass them through.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, no_subset_tables)
+
+// Tables which should be dropped.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, drop_tables)
+
+// Old -> New glyph id mapping
+HB_SUBSET_PLAN_MEMBER (hb_map_t, glyph_map_gsub)
+
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_gsub)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_mathed)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_colred)
+
+//active lookups we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_lookups)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_lookups)
+
+//active langsys we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_langsys)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_langsys)
+
+//active features after removing redundant langsys and prune_features
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features)
+
+//active feature variation records/condition index with variations
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_feature_record_cond_idx_map)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_feature_record_cond_idx_map)
+
+//feature index-> address of substituation feature table mapping with
+//variations
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gsub_feature_substitutes_map)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gpos_feature_substitutes_map)
+
+//active layers/palettes we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_layers)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes)
+
+//Old layout item variation index -> (New varidx, delta) mapping
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), layout_variation_idx_delta_map)
+
+//gdef varstore retained varidx mapping
+HB_SUBSET_PLAN_MEMBER (hb_vector_t, gdef_varstore_inner_maps)
+
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), sanitized_table_cache)
+
+//normalized axes range map
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), axes_location)
+HB_SUBSET_PLAN_MEMBER (hb_vector_t, normalized_coords)
+
+//user specified axes range map
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), user_axes_location)
+//axis->TripleDistances map (distances in the pre-normalized space)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), axes_triple_distances)
+
+//retained old axis index -> new axis index mapping in fvar axis array
+HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map)
+
+//axis_index->axis_tag mapping in fvar axis array
+HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_old_index_tag_map)
+//vector of retained axis tags in the order of axes given in the 'fvar' table
+HB_SUBSET_PLAN_MEMBER (hb_vector_t, axis_tags)
+
+//hmtx metrics map: new gid->(advance, lsb)
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), hmtx_map)
+//vmtx metrics map: new gid->(advance, lsb)
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), vmtx_map)
+//boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin
+HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t, bounds_width_vec)
+//boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
+HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t, bounds_height_vec)
+
+//map: new_gid -> contour points vector
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(), new_gid_contour_points_map)
+
+#ifdef HB_EXPERIMENTAL_API
+// name table overrides map: hb_ot_name_record_ids_t-> name string new value or
+// None to indicate should remove
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), name_table_overrides)
+#endif
+
+#undef E
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc	2024-01-16 16:19:00.000000000 +0000
@@ -48,10 +48,24 @@
 using OT::Layout::GSUB;
 using OT::Layout::GPOS;
 
+
+hb_subset_accelerator_t::~hb_subset_accelerator_t ()
+{
+  if (cmap_cache && destroy_cmap_cache)
+    destroy_cmap_cache ((void*) cmap_cache);
+
+#ifndef HB_NO_SUBSET_CFF
+  cff1_accel.fini ();
+  cff2_accel.fini ();
+#endif
+  hb_face_destroy (source);
+}
+
+
 typedef hb_hashmap_t> script_langsys_map;
 #ifndef HB_NO_SUBSET_CFF
 static inline bool
-_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
+_add_cff_seac_components (const OT::cff1::accelerator_subset_t &cff,
                           hb_codepoint_t gid,
                           hb_set_t *gids_to_retain)
 {
@@ -135,7 +149,8 @@
                                      hb_set_t             *lookup_indices, /* OUT */
                                      hb_set_t             *feature_indices, /* OUT */
                                      hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */
-                                     hb_hashmap_t *feature_substitutes_map /* OUT */)
+                                     hb_hashmap_t *feature_substitutes_map, /* OUT */
+                                     bool& insert_catch_all_feature_variation_record)
 {
   unsigned num_features = table.get_feature_count ();
   hb_vector_t features;
@@ -171,8 +186,11 @@
       &plan->axes_location,
       feature_record_cond_idx_map,
       feature_substitutes_map,
+      insert_catch_all_feature_variation_record,
       feature_indices,
-      true,
+      false,
+      false,
+      false,
       0,
       &conditionset_map
     };
@@ -283,7 +301,8 @@
                                   hb_map_t           *features,
                                   script_langsys_map *langsys_map,
                                   hb_hashmap_t> *feature_record_cond_idx_map,
-                                  hb_hashmap_t *feature_substitutes_map)
+                                  hb_hashmap_t *feature_substitutes_map,
+                                  bool& insert_catch_all_feature_variation_record)
 {
   hb_blob_ptr_t table = plan->source_table ();
   hb_tag_t table_tag = table->tableTag;
@@ -293,7 +312,8 @@
                               &lookup_indices,
                               &feature_indices,
                               feature_record_cond_idx_map,
-                              feature_substitutes_map);
+                              feature_substitutes_map,
+                              insert_catch_all_feature_variation_record);
 
   if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE))
     hb_ot_layout_lookups_substitute_closure (plan->source,
@@ -329,7 +349,7 @@
 {
   if (varidx_set.is_empty () || subtable_count == 0) return;
 
-  inner_maps.resize (subtable_count);
+  if (unlikely (!inner_maps.resize (subtable_count))) return;
   for (unsigned idx : varidx_set)
   {
     uint16_t major = idx >> 16;
@@ -356,7 +376,7 @@
   {
     hb_variation_t var;
     var.tag = _.first;
-    var.value = _.second;
+    var.value = _.second.middle;
     vars.push (var);
   }
 
@@ -379,42 +399,20 @@
     return;
   }
 
-  const OT::VariationStore *var_store = nullptr;
   hb_set_t varidx_set;
-  hb_font_t *font = nullptr;
-  float *store_cache = nullptr;
-  bool collect_delta = plan->pinned_at_default ? false : true;
-  if (collect_delta)
-  {
-    if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) {
-      hb_font_destroy (font);
-      gdef.destroy ();
-      gpos.destroy ();
-      return;
-    }
-
-    if (gdef->has_var_store ())
-    {
-      var_store = &(gdef->get_var_store ());
-      store_cache = var_store->create_cache ();
-    }
-  }
-
   OT::hb_collect_variation_indices_context_t c (&varidx_set,
-                                                &plan->layout_variation_idx_delta_map,
-                                                font, var_store,
                                                 &plan->_glyphset_gsub,
-                                                &plan->gpos_lookups,
-                                                store_cache);
+                                                &plan->gpos_lookups);
   gdef->collect_variation_indices (&c);
 
   if (hb_ot_layout_has_positioning (plan->source))
     gpos->collect_variation_indices (&c);
 
-  hb_font_destroy (font);
-  var_store->destroy_cache (store_cache);
-
-  gdef->remap_layout_variation_indices (&varidx_set, &plan->layout_variation_idx_delta_map);
+  gdef->remap_layout_variation_indices (&varidx_set,
+                                        plan->normalized_coords,
+                                        !plan->pinned_at_default,
+                                        plan->all_axes_pinned,
+                                        &plan->layout_variation_idx_delta_map);
 
   unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0;
   _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps);
@@ -549,6 +547,8 @@
         unicodes->get_population () < cmap_unicodes->get_population () &&
         glyphs->get_population () < cmap_unicodes->get_population ())
     {
+      plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ());
+
       auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes;
       for (hb_codepoint_t gid : *glyphs)
       {
@@ -577,6 +577,7 @@
     }
     else
     {
+      plan->codepoint_to_glyph->alloc (cmap_unicodes->get_population ());
       for (hb_codepoint_t cp : *cmap_unicodes)
       {
         hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
@@ -589,11 +590,15 @@
     }
 
     /* Add gids which where requested, but not mapped in cmap */
-    for (hb_codepoint_t gid : *glyphs)
+    unsigned num_glyphs = plan->source->get_num_glyphs ();
+    hb_codepoint_t first = HB_SET_VALUE_INVALID, last = HB_SET_VALUE_INVALID;
+    for (; glyphs->next_range (&first, &last); )
     {
-      if (gid >= plan->source->get_num_glyphs ())
+      if (first >= num_glyphs)
         break;
-      plan->_glyphset_gsub.add (gid);
+      if (last >= num_glyphs)
+        last = num_glyphs - 1;
+      plan->_glyphset_gsub.add_range (first, last);
     }
   }
 
@@ -616,14 +621,17 @@
                             int operation_count,
                             unsigned depth = 0)
 {
-  if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
-  if (unlikely (--operation_count < 0)) return operation_count;
   /* Check if is already visited */
   if (gids_to_retain->has (gid)) return operation_count;
 
   gids_to_retain->add (gid);
 
-  for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ())
+  if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
+  if (unlikely (--operation_count < 0)) return operation_count;
+
+  auto glyph = glyf.glyph_for_gid (gid);
+
+  for (auto &item : glyph.get_composite_iterator ())
     operation_count =
       _glyf_add_gid_and_children (glyf,
                                   item.get_gid (),
@@ -632,7 +640,7 @@
                                   depth);
 
 #ifndef HB_NO_VAR_COMPOSITES
-  for (auto &item : glyf.glyph_for_gid (gid).get_var_composite_iterator ())
+  for (auto &item : glyph.get_var_composite_iterator ())
    {
     operation_count =
       _glyf_add_gid_and_children (glyf,
@@ -655,7 +663,7 @@
 #endif
 #ifndef HB_NO_VAR
   if (!plan->all_axes_pinned)
-    plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
+    plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->axes_old_index_tag_map, &plan->name_ids);
 #endif
 #ifndef HB_NO_COLOR
   if (!drop_tables->has (HB_OT_TAG_CPAL))
@@ -684,7 +692,11 @@
 {
   OT::glyf_accelerator_t glyf (plan->source);
 #ifndef HB_NO_SUBSET_CFF
-  OT::cff1::accelerator_t cff (plan->source);
+  // Note: we cannot use inprogress_accelerator here, since it has not been
+  // created yet. So in case of preprocessed-face (and otherwise), we do an
+  // extra sanitize pass here, which is not ideal.
+  OT::cff1::accelerator_subset_t stack_cff (plan->accelerator ? nullptr : plan->source);
+  const OT::cff1::accelerator_subset_t *cff (plan->accelerator ? plan->accelerator->cff1_accel.get () : &stack_cff);
 #endif
 
   plan->_glyphset_gsub.add (0); // Not-def
@@ -701,7 +713,8 @@
         &plan->gsub_features,
         &plan->gsub_langsys,
         &plan->gsub_feature_record_cond_idx_map,
-        &plan->gsub_feature_substitutes_map);
+        &plan->gsub_feature_substitutes_map,
+        plan->gsub_insert_catch_all_feature_variation_rec);
 
   if (!drop_tables->has (HB_OT_TAG_GPOS))
     _closure_glyphs_lookups_features (
@@ -711,7 +724,8 @@
         &plan->gpos_features,
         &plan->gpos_langsys,
         &plan->gpos_feature_record_cond_idx_map,
-        &plan->gpos_feature_substitutes_map);
+        &plan->gpos_feature_substitutes_map,
+        plan->gpos_insert_catch_all_feature_variation_rec);
 #endif
   _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ());
 
@@ -744,9 +758,9 @@
   if (!plan->accelerator || plan->accelerator->has_seac)
   {
     bool has_seac = false;
-    if (cff.is_valid ())
+    if (cff->is_valid ())
       for (hb_codepoint_t gid : cur_glyphset)
-        if (_add_cff_seac_components (cff, gid, &plan->_glyphset))
+        if (_add_cff_seac_components (*cff, gid, &plan->_glyphset))
           has_seac = true;
     plan->has_seac = has_seac;
   }
@@ -754,7 +768,6 @@
 
   _remove_invalid_gids (&plan->_glyphset, plan->source->get_num_glyphs ());
 
-
 #ifndef HB_NO_VAR
   if (!drop_tables->has (HB_OT_TAG_GDEF))
     _collect_layout_variation_indices (plan);
@@ -766,41 +779,90 @@
                         const hb_map_t* glyph_map,
                         hb_map_t* out)
 {
+  out->alloc (glyph_set_gsub->get_population ());
   + hb_iter (glyph_set_gsub)
   | hb_map ([&] (hb_codepoint_t gid) {
-    return hb_pair_t (gid,
-                                                      glyph_map->get (gid));
+    return hb_codepoint_pair_t (gid, glyph_map->get (gid));
   })
   | hb_sink (out)
   ;
 }
 
-static void
+static bool
 _create_old_gid_to_new_gid_map (const hb_face_t *face,
                                 bool             retain_gids,
                                 const hb_set_t  *all_gids_to_retain,
+                                const hb_map_t  *requested_glyph_map,
                                 hb_map_t        *glyph_map, /* OUT */
                                 hb_map_t        *reverse_glyph_map, /* OUT */
+                                hb_sorted_vector_t *new_to_old_gid_list /* OUT */,
                                 unsigned int    *num_glyphs /* OUT */)
 {
   unsigned pop = all_gids_to_retain->get_population ();
-  reverse_glyph_map->resize (pop);
-  glyph_map->resize (pop);
+  reverse_glyph_map->alloc (pop);
+  glyph_map->alloc (pop);
+  new_to_old_gid_list->alloc (pop);
+
+  if (*requested_glyph_map)
+  {
+    hb_set_t new_gids(requested_glyph_map->values());
+    if (new_gids.get_population() != requested_glyph_map->get_population())
+    {
+      DEBUG_MSG (SUBSET, nullptr, "The provided custom glyph mapping is not unique.");
+      return false;
+    }
+
+    if (retain_gids)
+    {
+      DEBUG_MSG (SUBSET, nullptr,
+        "HB_SUBSET_FLAGS_RETAIN_GIDS cannot be set if "
+        "a custom glyph mapping has been provided.");
+      return false;
+    }
+
+    hb_codepoint_t max_glyph = 0;
+    hb_set_t remaining;
+    for (auto old_gid : all_gids_to_retain->iter ())
+    {
+      if (old_gid == 0) {
+        new_to_old_gid_list->push (hb_pair (0u, 0u));
+        continue;
+      }
 
-  if (!retain_gids)
+      hb_codepoint_t* new_gid;
+      if (!requested_glyph_map->has (old_gid, &new_gid))
+      {
+        remaining.add(old_gid);
+        continue;
+      }
+
+      if (*new_gid > max_glyph)
+        max_glyph = *new_gid;
+      new_to_old_gid_list->push (hb_pair (*new_gid, old_gid));
+    }
+    new_to_old_gid_list->qsort ();
+
+    // Anything that wasn't mapped by the requested mapping should
+    // be placed after the requested mapping.
+    for (auto old_gid : remaining)
+      new_to_old_gid_list->push (hb_pair (++max_glyph, old_gid));
+
+    *num_glyphs = max_glyph + 1;
+  }
+  else if (!retain_gids)
   {
     + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0)
-    | hb_sink (reverse_glyph_map)
+    | hb_sink (new_to_old_gid_list)
     ;
-    *num_glyphs = reverse_glyph_map->get_population ();
+    *num_glyphs = new_to_old_gid_list->length;
   }
   else
   {
     + hb_iter (all_gids_to_retain)
     | hb_map ([] (hb_codepoint_t _) {
-                return hb_pair_t (_, _);
+                return hb_codepoint_pair_t (_, _);
               })
-    | hb_sink (reverse_glyph_map)
+    | hb_sink (new_to_old_gid_list)
     ;
 
     hb_codepoint_t max_glyph = HB_SET_VALUE_INVALID;
@@ -809,10 +871,15 @@
     *num_glyphs = max_glyph + 1;
   }
 
-  + reverse_glyph_map->iter ()
-  | hb_map (&hb_pair_t::reverse)
+  + hb_iter (new_to_old_gid_list)
+  | hb_sink (reverse_glyph_map)
+  ;
+  + hb_iter (new_to_old_gid_list)
+  | hb_map (&hb_codepoint_pair_t::reverse)
   | hb_sink (glyph_map)
   ;
+
+  return true;
 }
 
 #ifndef HB_NO_VAR
@@ -841,24 +908,38 @@
     hb_tag_t axis_tag = axis.get_axis_tag ();
     plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag);
 
-    if (!plan->user_axes_location.has (axis_tag))
+    if (!plan->user_axes_location.has (axis_tag) ||
+        !plan->user_axes_location.get (axis_tag).is_point ())
     {
       axis_not_pinned = true;
       plan->axes_index_map.set (old_axis_idx, new_axis_idx);
+      plan->axis_tags.push (axis_tag);
       new_axis_idx++;
     }
-    else
+
+    Triple *axis_range;
+    if (plan->user_axes_location.has (axis_tag, &axis_range))
     {
-      int normalized_v = axis.normalize_axis_value (plan->user_axes_location.get (axis_tag));
+      plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ());
+
+      int normalized_min = axis.normalize_axis_value (axis_range->minimum);
+      int normalized_default = axis.normalize_axis_value (axis_range->middle);
+      int normalized_max = axis.normalize_axis_value (axis_range->maximum);
+
       if (has_avar && old_axis_idx < avar_axis_count)
       {
-        normalized_v = seg_maps->map (normalized_v);
+        normalized_min = seg_maps->map (normalized_min);
+        normalized_default = seg_maps->map (normalized_default);
+        normalized_max = seg_maps->map (normalized_max);
       }
-      plan->axes_location.set (axis_tag, normalized_v);
-      if (normalized_v != 0)
+      plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.f),
+                                                 static_cast (normalized_default / 16384.f),
+                                                 static_cast (normalized_max / 16384.f)));
+
+      if (normalized_default != 0)
         plan->pinned_at_default = false;
 
-      plan->normalized_coords[old_axis_idx] = normalized_v;
+      plan->normalized_coords[old_axis_idx] = normalized_default;
     }
 
     old_axis_idx++;
@@ -925,7 +1006,7 @@
           continue;
       }
       plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
-      plan->bounds_width_map.set (new_gid, extents.width);
+      plan->bounds_width_vec[new_gid] = extents.width;
     }
 
     if (_vmtx.has_data ())
@@ -942,7 +1023,7 @@
           continue;
       }
       plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
-      plan->bounds_height_map.set (new_gid, extents.height);
+      plan->bounds_height_vec[new_gid] = extents.height;
     }
   }
   hb_font_destroy (font);
@@ -951,6 +1032,36 @@
   if (vvar_store_cache)
     _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache);
 }
+
+static bool
+_get_instance_glyphs_contour_points (hb_subset_plan_t *plan)
+{
+  /* contour_points vector only needed for updating gvar table (infer delta)
+   * during partial instancing */
+  if (plan->user_axes_location.is_empty () || plan->all_axes_pinned)
+    return true;
+
+  OT::glyf_accelerator_t glyf (plan->source);
+
+  for (auto &_ : plan->new_to_old_gid_list)
+  {
+    hb_codepoint_t new_gid = _.first;
+    contour_point_vector_t all_points;
+    if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+    {
+      if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points)))
+        return false;
+      continue;
+    }
+
+    hb_codepoint_t old_gid = _.second;
+    if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points)))
+      return false;
+    if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points)))
+      return false;
+  }
+  return true;
+}
 #endif
 
 hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
@@ -975,6 +1086,8 @@
   glyph_map = hb_map_create ();
   reverse_glyph_map = hb_map_create ();
 
+  gsub_insert_catch_all_feature_variation_rec = false;
+  gpos_insert_catch_all_feature_variation_rec = false;
   gdef_varstore_inner_maps.init ();
 
   user_axes_location = input->axes_location;
@@ -1002,7 +1115,6 @@
   if (accel)
     accelerator = (hb_subset_accelerator_t*) accel;
 
-
   if (unlikely (in_error ()))
     return;
 
@@ -1016,12 +1128,17 @@
   if (unlikely (in_error ()))
     return;
 
-  _create_old_gid_to_new_gid_map (face,
-                                  input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
-                                  &_glyphset,
-                                  glyph_map,
-                                  reverse_glyph_map,
-                                  &_num_output_glyphs);
+  if (!check_success(_create_old_gid_to_new_gid_map(
+          face,
+          input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
+          &_glyphset,
+          &input->glyph_map,
+          glyph_map,
+          reverse_glyph_map,
+          &new_to_old_gid_list,
+          &_num_output_glyphs))) {
+    return;
+  }
 
   _create_glyph_map_gsub (
       &_glyphset_gsub,
@@ -1036,33 +1153,61 @@
         glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second);
   }
 
+  bounds_width_vec.resize (_num_output_glyphs, false);
+  for (auto &v : bounds_width_vec)
+    v = 0xFFFFFFFF;
+  bounds_height_vec.resize (_num_output_glyphs, false);
+  for (auto &v : bounds_height_vec)
+    v = 0xFFFFFFFF;
+
   if (unlikely (in_error ()))
     return;
 
 #ifndef HB_NO_VAR
   _update_instance_metrics_map_from_cff2 (this);
+  if (!check_success (_get_instance_glyphs_contour_points (this)))
+      return;
 #endif
 
   if (attach_accelerator_data)
   {
-    hb_multimap_t gid_to_unicodes;
-
-    hb_map_t &unicode_to_gid = *codepoint_to_glyph;
-
-    for (auto unicode : unicodes)
-    {
-      auto gid = unicode_to_gid[unicode];
-      gid_to_unicodes.add (gid, unicode);
-    }
-
     inprogress_accelerator =
-      hb_subset_accelerator_t::create (*codepoint_to_glyph,
-                                       gid_to_unicodes,
+      hb_subset_accelerator_t::create (source,
+                                       *codepoint_to_glyph,
                                        unicodes,
                                        has_seac);
+
+    check_success (inprogress_accelerator);
   }
+
+#define HB_SUBSET_PLAN_MEMBER(Type, Name) check_success (!Name.in_error ());
+#include "hb-subset-plan-member-list.hh"
+#undef HB_SUBSET_PLAN_MEMBER
 }
 
+hb_subset_plan_t::~hb_subset_plan_t()
+{
+  hb_face_destroy (dest);
+
+  hb_map_destroy (codepoint_to_glyph);
+  hb_map_destroy (glyph_map);
+  hb_map_destroy (reverse_glyph_map);
+#ifndef HB_NO_SUBSET_CFF
+  cff1_accel.fini ();
+  cff2_accel.fini ();
+#endif
+  hb_face_destroy (source);
+
+#ifdef HB_EXPERIMENTAL_API
+  for (auto _ : name_table_overrides.iter_ref ())
+    _.second.fini ();
+#endif
+
+  if (inprogress_accelerator)
+    hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator);
+}
+
+
 /**
  * hb_subset_plan_create_or_fail:
  * @face: font face to create the plan for.
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh	2024-01-16 16:19:00.000000000 +0000
@@ -67,28 +67,51 @@
 
 typedef struct head_maxp_info_t head_maxp_info_t;
 
-struct hb_subset_plan_t
+struct contour_point_t
 {
-  HB_INTERNAL hb_subset_plan_t (hb_face_t *,
-                                const hb_subset_input_t *input);
+  void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
+  { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
 
-  ~hb_subset_plan_t()
+  void transform (const float (&matrix)[4])
   {
-    hb_face_destroy (source);
-    hb_face_destroy (dest);
+    float x_ = x * matrix[0] + y * matrix[2];
+          y  = x * matrix[1] + y * matrix[3];
+    x  = x_;
+  }
+  HB_ALWAYS_INLINE
+  void translate (const contour_point_t &p) { x += p.x; y += p.y; }
 
-    hb_map_destroy (codepoint_to_glyph);
-    hb_map_destroy (glyph_map);
-    hb_map_destroy (reverse_glyph_map);
-
-#ifdef HB_EXPERIMENTAL_API
-    for (auto _ : name_table_overrides)
-      _.second.fini ();
-#endif
 
-    if (inprogress_accelerator)
-      hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator);
+  float x;
+  float y;
+  uint8_t flag;
+  bool is_end_point;
+};
+
+struct contour_point_vector_t : hb_vector_t
+{
+  void extend (const hb_array_t &a)
+  {
+    unsigned int old_len = length;
+    if (unlikely (!resize (old_len + a.length, false)))
+      return;
+    auto arrayZ = this->arrayZ + old_len;
+    unsigned count = a.length;
+    hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
   }
+};
+
+namespace OT {
+  struct cff1_subset_accelerator_t;
+  struct cff2_subset_accelerator_t;
+}
+
+struct hb_subset_plan_t
+{
+  HB_INTERNAL hb_subset_plan_t (hb_face_t *,
+                                const hb_subset_input_t *input);
+
+  HB_INTERNAL ~hb_subset_plan_t();
 
   hb_object_header_t header;
 
@@ -97,137 +120,71 @@
   bool attach_accelerator_data = false;
   bool force_long_loca = false;
 
-  // For each cp that we'd like to retain maps to the corresponding gid.
-  hb_set_t unicodes;
-  hb_sorted_vector_t> unicode_to_new_gid_list;
-
-  // name_ids we would like to retain
-  hb_set_t name_ids;
-
-  // name_languages we would like to retain
-  hb_set_t name_languages;
-
-  //layout features which will be preserved
-  hb_set_t layout_features;
-
-  // layout scripts which will be preserved.
-  hb_set_t layout_scripts;
-
-  //glyph ids requested to retain
-  hb_set_t glyphs_requested;
-
-  // Tables which should not be processed, just pass them through.
-  hb_set_t no_subset_tables;
-
-  // Tables which should be dropped.
-  hb_set_t drop_tables;
-
   // The glyph subset
   hb_map_t *codepoint_to_glyph; // Needs to be heap-allocated
 
   // Old -> New glyph id mapping
   hb_map_t *glyph_map; // Needs to be heap-allocated
   hb_map_t *reverse_glyph_map; // Needs to be heap-allocated
-  hb_map_t glyph_map_gsub;
 
   // Plan is only good for a specific source/dest so keep them with it
   hb_face_t *source;
+#ifndef HB_NO_SUBSET_CFF
+  // These have to be immediately after source:
+  hb_face_lazy_loader_t cff1_accel;
+  hb_face_lazy_loader_t cff2_accel;
+#endif
+
   hb_face_t *dest;
 
   unsigned int _num_output_glyphs;
-  hb_set_t _glyphset;
-  hb_set_t _glyphset_gsub;
-  hb_set_t _glyphset_mathed;
-  hb_set_t _glyphset_colred;
-
-  //active lookups we'd like to retain
-  hb_map_t gsub_lookups;
-  hb_map_t gpos_lookups;
-
-  //active langsys we'd like to retain
-  hb_hashmap_t> gsub_langsys;
-  hb_hashmap_t> gpos_langsys;
-
-  //active features after removing redundant langsys and prune_features
-  hb_map_t gsub_features;
-  hb_map_t gpos_features;
-
-  //active feature variation records/condition index with variations
-  hb_hashmap_t> gsub_feature_record_cond_idx_map;
-  hb_hashmap_t> gpos_feature_record_cond_idx_map;
-
-  //feature index-> address of substituation feature table mapping with
-  //variations
-  hb_hashmap_t gsub_feature_substitutes_map;
-  hb_hashmap_t gpos_feature_substitutes_map;
-
-  //active layers/palettes we'd like to retain
-  hb_map_t colrv1_layers;
-  hb_map_t colr_palettes;
-
-  //Old layout item variation index -> (New varidx, delta) mapping
-  hb_hashmap_t> layout_variation_idx_delta_map;
-
-  //gdef varstore retained varidx mapping
-  hb_vector_t gdef_varstore_inner_maps;
-
-  hb_hashmap_t> sanitized_table_cache;
-  //normalized axes location map
-  hb_hashmap_t axes_location;
-  hb_vector_t normalized_coords;
-  //user specified axes location map
-  hb_hashmap_t user_axes_location;
-  //retained old axis index -> new axis index mapping in fvar axis array
-  hb_map_t axes_index_map;
-  //axis_index->axis_tag mapping in fvar axis array
-  hb_map_t axes_old_index_tag_map;
+
   bool all_axes_pinned;
   bool pinned_at_default;
   bool has_seac;
 
-  //hmtx metrics map: new gid->(advance, lsb)
-  mutable hb_hashmap_t> hmtx_map;
-  //vmtx metrics map: new gid->(advance, lsb)
-  mutable hb_hashmap_t> vmtx_map;
-  //boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin
-  mutable hb_map_t bounds_width_map;
-  //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
-  mutable hb_map_t bounds_height_map;
+  // whether to insert a catch-all FeatureVariationRecord
+  bool gsub_insert_catch_all_feature_variation_rec;
+  bool gpos_insert_catch_all_feature_variation_rec;
+
+#define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name;
+#include "hb-subset-plan-member-list.hh"
+#undef HB_SUBSET_PLAN_MEMBER
 
   //recalculated head/maxp table info after instancing
   mutable head_maxp_info_t head_maxp_info;
 
-#ifdef HB_EXPERIMENTAL_API
-  // name table overrides map: hb_ot_name_record_ids_t-> name string new value or
-  // None to indicate should remove
-  hb_hashmap_t name_table_overrides;
-#endif
-
   const hb_subset_accelerator_t* accelerator;
   hb_subset_accelerator_t* inprogress_accelerator;
 
  public:
 
   template
-  hb_blob_ptr_t source_table()
+  struct source_table_loader
   {
-    hb_lock_t lock (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
+    hb_blob_ptr_t operator () (hb_subset_plan_t *plan)
+    {
+      hb_lock_t lock (plan->accelerator ? &plan->accelerator->sanitized_table_cache_lock : nullptr);
 
-    auto *cache = accelerator ? &accelerator->sanitized_table_cache : &sanitized_table_cache;
-    if (cache
-        && !cache->in_error ()
-        && cache->has (+T::tableTag)) {
-      return hb_blob_reference (cache->get (+T::tableTag).get ());
-    }
+      auto *cache = plan->accelerator ? &plan->accelerator->sanitized_table_cache : &plan->sanitized_table_cache;
+      if (cache
+          && !cache->in_error ()
+          && cache->has (+T::tableTag)) {
+        return hb_blob_reference (cache->get (+T::tableTag).get ());
+      }
 
-    hb::unique_ptr table_blob {hb_sanitize_context_t ().reference_table (source)};
-    hb_blob_t* ret = hb_blob_reference (table_blob.get ());
+      hb::unique_ptr table_blob {hb_sanitize_context_t ().reference_table (plan->source)};
+      hb_blob_t* ret = hb_blob_reference (table_blob.get ());
 
-    if (likely (cache))
-      cache->set (+T::tableTag, std::move (table_blob));
+      if (likely (cache))
+        cache->set (+T::tableTag, std::move (table_blob));
 
-    return ret;
-  }
+      return ret;
+    }
+  };
+
+  template
+  auto source_table() HB_AUTO_RETURN (source_table_loader {} (this))
 
   bool in_error () const { return !successful; }
 
@@ -266,15 +223,6 @@
     return _num_output_glyphs;
   }
 
-  /*
-   * Given an output gid , returns true if that glyph id is an empty
-   * glyph (ie. it's a gid that we are dropping all data for).
-   */
-  inline bool is_empty_glyph (hb_codepoint_t gid) const
-  {
-    return !_glyphset.has (gid);
-  }
-
   inline bool new_gid_for_codepoint (hb_codepoint_t codepoint,
                                      hb_codepoint_t *new_gid) const
   {
@@ -324,4 +272,5 @@
   }
 };
 
+
 #endif /* HB_SUBSET_PLAN_HH */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset.cc openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset.cc
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset.cc	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset.cc	2024-01-16 16:19:00.000000000 +0000
@@ -43,21 +43,19 @@
 #include "OT/Color/sbix/sbix.hh"
 #include "hb-ot-os2-table.hh"
 #include "hb-ot-post-table.hh"
-
-#if !defined(AIX) || defined(AIX_XLC_GE_17)
 #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"
 #include "hb-ot-name-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-var-avar-table.hh"
 #include "hb-ot-var-cvar-table.hh"
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-var-gvar-table.hh"
 #include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-var-mvar-table.hh"
 #include "hb-ot-math-table.hh"
 #include "hb-ot-stat-table.hh"
 #include "hb-repacker.hh"
@@ -66,6 +64,27 @@
 using OT::Layout::GSUB;
 using OT::Layout::GPOS;
 
+
+#ifndef HB_NO_SUBSET_CFF
+template<>
+struct hb_subset_plan_t::source_table_loader
+{
+  auto operator () (hb_subset_plan_t *plan)
+  HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel :
+                  plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel :
+                  plan->cff1_accel)
+};
+template<>
+struct hb_subset_plan_t::source_table_loader
+{
+  auto operator () (hb_subset_plan_t *plan)
+  HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel :
+                  plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel :
+                  plan->cff2_accel)
+};
+#endif
+
+
 /**
  * SECTION:hb-subset
  * @title: hb-subset
@@ -100,8 +119,8 @@
   HB_OT_TAG_BASE,
   HB_OT_TAG_CBDT,
   HB_OT_TAG_CBLC,
-  HB_OT_TAG_cff1,
-  HB_OT_TAG_cff2,
+  HB_OT_TAG_CFF1,
+  HB_OT_TAG_CFF2,
   HB_OT_TAG_cmap,
   HB_OT_TAG_COLR,
   HB_OT_TAG_CPAL,
@@ -196,15 +215,36 @@
 static unsigned
 _plan_estimate_subset_table_size (hb_subset_plan_t *plan,
                                   unsigned table_len,
-                                  bool same_size)
+                                  hb_tag_t table_tag)
 {
   unsigned src_glyphs = plan->source->get_num_glyphs ();
   unsigned dst_glyphs = plan->glyphset ()->get_population ();
 
+  unsigned bulk = 8192;
+  /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's
+   * because those are expensive to subset, so giving them more room is fine. */
+  bool same_size = table_tag == HB_OT_TAG_GSUB ||
+                   table_tag == HB_OT_TAG_GPOS ||
+                   table_tag == HB_OT_TAG_name;
+
+  if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS)
+  {
+    if (table_tag == HB_OT_TAG_CFF1)
+    {
+      /* Add some extra room for the CFF charset. */
+      bulk += src_glyphs * 16;
+    }
+    else if (table_tag == HB_OT_TAG_CFF2)
+    {
+      /* Just extra CharString offsets. */
+      bulk += src_glyphs * 4;
+    }
+  }
+
   if (unlikely (!src_glyphs) || same_size)
-    return 512 + table_len;
+    return bulk + table_len;
 
-  return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
+  return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
 }
 
 /*
@@ -235,7 +275,7 @@
              hb_vector_t* buf,
              hb_subset_context_t* c /* OUT */)
 {
-  c->serializer->start_serialize ();
+  c->serializer->start_serialize ();
   if (c->serializer->in_error ()) return false;
 
   bool needed = table->subset (c);
@@ -266,45 +306,46 @@
   return _try_subset (table, buf, c);
 }
 
+template 
+static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ())
+
+template 
+static void _do_destroy (T &t, hb_priority<0>) {}
+
 template
 static bool
 _subset (hb_subset_plan_t *plan, hb_vector_t &buf)
 {
-  hb_blob_ptr_t source_blob = plan->source_table ();
-  const TableType *table = source_blob.get ();
+  auto &&source_blob = plan->source_table ();
+  auto *table = source_blob.get ();
 
   hb_tag_t tag = TableType::tableTag;
-  if (!source_blob.get_blob()->data)
+  hb_blob_t *blob = source_blob.get_blob();
+  if (unlikely (!blob || !blob->data))
   {
     DEBUG_MSG (SUBSET, nullptr,
                "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
-    source_blob.destroy ();
+    _do_destroy (source_blob, hb_prioritize);
     return false;
   }
 
-  /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's
-   * because those are expensive to subset, so giving them more room is fine. */
-  bool same_size_table = TableType::tableTag == HB_OT_TAG_GSUB ||
-                         TableType::tableTag == HB_OT_TAG_GPOS ||
-                         TableType::tableTag == HB_OT_TAG_name;
-
-  unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob.get_length (), same_size_table);
+  unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag);
   DEBUG_MSG (SUBSET, nullptr,
              "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
   if (unlikely (!buf.alloc (buf_size)))
   {
     DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
-    source_blob.destroy ();
+    _do_destroy (source_blob, hb_prioritize);
     return false;
   }
 
   bool needed = false;
   hb_serialize_context_t serializer (buf.arrayZ, buf.allocated);
   {
-    hb_subset_context_t c (source_blob.get_blob (), plan, &serializer, tag);
+    hb_subset_context_t c (blob, plan, &serializer, tag);
     needed = _try_subset (table, &buf, &c);
   }
-  source_blob.destroy ();
+  _do_destroy (source_blob, hb_prioritize);
 
   if (serializer.in_error () && !serializer.only_offset_overflow ())
   {
@@ -420,6 +461,8 @@
   case HB_OT_TAG_vmtx:
   case HB_OT_TAG_maxp:
     return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf);
+  case HB_OT_TAG_GPOS:
+    return !plan->normalized_coords || plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF);
   default:
     return true;
   }
@@ -461,8 +504,8 @@
   case HB_OT_TAG_MATH: return _subset (plan, buf);
 
 #ifndef HB_NO_SUBSET_CFF
-  case HB_OT_TAG_cff1: return _subset (plan, buf);
-  case HB_OT_TAG_cff2: return _subset (plan, buf);
+  case HB_OT_TAG_CFF1: return _subset (plan, buf);
+  case HB_OT_TAG_CFF2: return _subset (plan, buf);
   case HB_OT_TAG_VORG: return _subset (plan, buf);
 #endif
 
@@ -474,13 +517,24 @@
   case HB_OT_TAG_HVAR: return _subset (plan, buf);
   case HB_OT_TAG_VVAR: return _subset (plan, buf);
 #endif
+
+#ifndef HB_NO_VAR
   case HB_OT_TAG_fvar:
     if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
     return _subset (plan, buf);
+  case HB_OT_TAG_avar:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset (plan, buf);
+  case HB_OT_TAG_cvar:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset (plan, buf);
+  case HB_OT_TAG_MVAR:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset (plan, buf);
+#endif
+
   case HB_OT_TAG_STAT:
-    /*TODO(qxliu): change the condition as we support more complex
-     * instancing operation*/
-    if (plan->all_axes_pinned) return _subset (plan, buf);
+    if (!plan->user_axes_location.is_empty ()) return _subset (plan, buf);
     else return _passthrough (plan, tag);
 
   case HB_TAG ('c', 'v', 't', ' '):
@@ -591,46 +645,49 @@
     offset += num_tables;
   }
 
-  hb_vector_t buf;
-  buf.alloc (4096 - 16);
-
-
   bool success = true;
 
-  while (!pending_subset_tags.is_empty ())
   {
-    if (subsetted_tags.in_error ()
-        || pending_subset_tags.in_error ()) {
-      success = false;
-      goto end;
-    }
+    // Grouping to deallocate buf before calling hb_face_reference (plan->dest).
 
-    bool made_changes = false;
-    for (hb_tag_t tag : pending_subset_tags)
+    hb_vector_t buf;
+    buf.alloc (8192 - 16);
+
+    while (!pending_subset_tags.is_empty ())
     {
-      if (!_dependencies_satisfied (plan, tag,
-                                    subsetted_tags,
-                                    pending_subset_tags))
-      {
-        // delayed subsetting for some tables since they might have dependency on other tables
-        // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated
-        // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values
-        continue;
+      if (subsetted_tags.in_error ()
+          || pending_subset_tags.in_error ()) {
+        success = false;
+        goto end;
       }
 
-      pending_subset_tags.del (tag);
-      subsetted_tags.add (tag);
-      made_changes = true;
+      bool made_changes = false;
+      for (hb_tag_t tag : pending_subset_tags)
+      {
+        if (!_dependencies_satisfied (plan, tag,
+                                      subsetted_tags,
+                                      pending_subset_tags))
+        {
+          // delayed subsetting for some tables since they might have dependency on other tables
+          // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated
+          // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values
+          continue;
+        }
+
+        pending_subset_tags.del (tag);
+        subsetted_tags.add (tag);
+        made_changes = true;
 
-      success = _subset_table (plan, buf, tag);
-      if (unlikely (!success)) goto end;
-    }
+        success = _subset_table (plan, buf, tag);
+        if (unlikely (!success)) goto end;
+      }
 
-    if (!made_changes)
-    {
-      DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed.");
-      success = false;
-      goto end;
+      if (!made_changes)
+      {
+        DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed.");
+        success = false;
+        goto end;
+      }
     }
   }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-subset.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-subset.h	2024-01-16 16:19:00.000000000 +0000
@@ -154,6 +154,9 @@
 HB_EXTERN hb_set_t *
 hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type);
 
+HB_EXTERN hb_map_t*
+hb_subset_input_old_to_new_glyph_mapping (hb_subset_input_t *input);
+
 HB_EXTERN hb_subset_flags_t
 hb_subset_input_get_flags (hb_subset_input_t *input);
 
@@ -174,6 +177,14 @@
 
 #ifdef HB_EXPERIMENTAL_API
 HB_EXTERN hb_bool_t
+hb_subset_input_set_axis_range (hb_subset_input_t  *input,
+                                hb_face_t          *face,
+                                hb_tag_t            axis_tag,
+                                float               axis_min_value,
+                                float               axis_max_value,
+                                float              *axis_def_value);
+
+HB_EXTERN hb_bool_t
 hb_subset_input_override_name_table (hb_subset_input_t  *input,
                                      hb_ot_name_id_t     name_id,
                                      unsigned            platform_id,
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -4,7 +4,7 @@
  *
  *   ./gen-ucd-table.py ucd.nounihan.grouped.xml
  *
- * on file with this description: Unicode 15.0.0
+ * on file with this description: Unicode 15.1.0
  */
 
 #ifndef HB_UCD_TABLE_HH
@@ -1069,7 +1069,7 @@
 #ifndef HB_OPTIMIZE_SIZE
 
 static const uint8_t
-_hb_ucd_u8[17868] =
+_hb_ucd_u8[17884] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7, 11, 12, 13, 13, 13, 14,
@@ -1146,13 +1146,13 @@
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
   244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
-  250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
-  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
+   34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122,
+   34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122,
+   34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122,
+  251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122,
   107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
+  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255,
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
     7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
@@ -1315,11 +1315,11 @@
   121,  4,  4,  4,  4,  2,  2, 88,  2,  2,  2,  2,  2,120,  2,  2,
   108,151,  2,  2,  2,  2,  2,  2, 67,  2,152,148,148,148,153, 44,
    67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
-    1,  2,154,155,  4,  4,  4,  4,  4, 67,  4,  4,  4,  4,156,157,
-  158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
-   36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
-   44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
+   67, 67, 67, 44, 44, 44, 44, 44,  1,  2,154,155,  4,  4,  4,  4,
+    4, 67,  4,  4,  4,  4,156,157,158,105,105,105,105, 43, 43, 86,
+  159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69,
+   36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36,
+   67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55,
    67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
    67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
    36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164,  2,
@@ -1487,215 +1487,215 @@
    44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
    62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
    36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
-    8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
-   27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
-   44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
-   67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
-   67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
-  171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171,  0,
-    0,  0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
-   25, 25, 25, 21, 21,  9,  9,  9,  9, 22, 21, 18, 24, 16, 24,  5,
-    5,  5,  5, 22, 25, 18, 25,  0, 23, 23, 26, 21, 24, 26,  7, 20,
-   25,  1, 26, 24, 26, 25, 15, 15, 24, 15,  7, 19, 15, 21,  9, 25,
-    9,  5,  5, 25,  5,  9,  5,  7,  7,  7,  9,  8,  8,  5,  7,  5,
-    6,  6, 24, 24,  6, 24, 12, 12,  2,  2,  6,  5,  9, 21,  9,  2,
-    2,  9, 25,  9, 26, 12, 11, 11,  2,  6,  5, 21, 17,  2,  2, 26,
-   26, 23,  2, 12, 17, 12, 21, 12, 12, 21,  7,  2,  2,  7,  7, 21,
-   21,  2,  1,  1, 21, 23, 26, 26,  1, 21,  6,  7,  7, 12, 12,  7,
-   21,  7, 12,  1, 12,  6,  6, 12, 12, 26,  7, 26, 26,  7,  2,  1,
-   12,  2,  6,  2, 24,  7,  7,  6,  1, 12, 12, 10, 10, 10, 10, 12,
-   21,  6,  2, 10, 10,  2, 15, 26, 26,  2,  2, 21,  7, 10, 15,  7,
-    2, 23, 21, 26, 10,  7, 21, 15, 15,  2, 17,  7, 29,  7,  7, 22,
-   18,  2, 14, 14, 14,  7, 10, 21, 17, 21, 11, 12,  5,  2,  5,  6,
-    8,  8,  8, 24,  5, 24,  2, 24,  9, 24, 24,  2, 29, 29, 29,  1,
-   17, 17, 20, 19, 22, 20, 27, 28,  1, 29, 21, 20, 19, 21, 21, 16,
-   16, 21, 25, 22, 18, 21, 21, 29,  1,  2, 15,  6, 18,  6, 23,  2,
-   12, 11,  9, 26, 26,  9, 26,  5,  5, 26, 14,  9,  5, 14, 14, 15,
-   25, 26, 26, 22, 18, 26, 18, 25, 18, 22,  5, 12,  2,  5, 22, 21,
-   21, 22, 18, 17, 26,  6,  7, 14, 17, 22, 18, 18, 26, 14, 17,  6,
-   14,  6, 12, 24, 24,  6, 26, 15,  6, 21, 11, 21, 24,  9,  6,  9,
-   23, 26,  6, 10,  4,  4,  3,  3,  7, 25, 17, 16, 16, 22, 16, 16,
-   25, 17, 25,  2, 25, 24,  2, 15, 12, 15, 14,  2, 21, 14,  7, 15,
-   12, 17, 21,  1, 26, 10, 10,  1, 23, 15,  0,  1,  2,  3,  4,  5,
-    6,  7,  8,  9,  0, 10, 11, 12, 13,  0, 14,  0,  0,  0,  0,  0,
-   15,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 18, 19,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 20,  0, 21, 22, 23,  0,  0,  0, 24,
-   25, 26, 27, 28, 29, 30, 31, 32, 33, 34,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 35,
-    0, 36,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,
-    0,  0, 38, 39,  0,  0,  0,  0,  0,  0, 40, 41, 42,  0, 43,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,
-    0,  0,  3,  0,  0,  0,  4,  5,  6,  7,  0,  8,  9, 10,  0, 11,
-   12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19,  0, 19,
-   16, 20, 16, 19, 21, 19,  0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-   31,  0, 32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33,  0,  0,
-    0,  0,  0,  0, 34,  0,  0, 35,  0,  0, 36,  0, 37,  0,  0,  0,
-   38, 39, 40, 41, 42, 43, 44, 45, 46,  0,  0, 47,  0,  0,  0, 48,
-    0,  0,  0, 49,  0,  0,  0,  0,  0,  0,  0, 50,  0, 51,  0, 52,
-   53,  0, 54,  0,  0,  0,  0,  0,  0, 55, 56, 57,  0,  0,  0,  0,
-   58,  0,  0, 59, 60, 61, 62, 63,  0,  0, 64, 65,  0,  0,  0, 66,
-    0,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 69,  0,  0,  0, 70,  0, 71,  0,  0,
-   72,  0,  0, 73,  0,  0,  0,  0,  0,  0,  0,  0, 74,  0,  0,  0,
-    0,  0, 75, 76,  0, 77, 78,  0,  0, 79, 80,  0, 81, 62,  0, 82,
-   83,  0,  0, 84, 85, 86,  0,  0,  0, 87,  0, 88,  0,  0, 51, 89,
-   51,  0, 90,  0, 91,  0,  0,  0, 80,  0,  0,  0, 92, 93,  0, 94,
-   95, 96, 97,  0,  0,  0,  0,  0, 51,  0,  0,  0,  0, 98, 99,  0,
-    0,  0,  0,  0,  0,100,  0,  0,  0,  0,  0,101,102,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,103,  0,  0,104,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,105,106,  0,  0,107,  0,  0,  0,  0,  0,  0,
-  108,  0,109,  0,102,  0,  0,  0,  0,  0,110,111,  0,  0,  0,  0,
-    0,  0,  0,112,  0,  0,  0,  0,  0,  0,  0,113,  0,114,  0,  0,
-    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  0,  8,  0,  0,  0,
-    0,  9, 10, 11, 12,  0,  0,  0,  0, 13,  0,  0, 14, 15,  0, 16,
-    0, 17, 18,  0,  0, 19,  0, 20, 21,  0,  0,  0,  0,  0, 22, 23,
-    0, 24, 25,  0,  0, 26,  0,  0,  0, 27,  0,  0, 28, 29, 30, 31,
-    0,  0,  0, 32, 33, 34,  0,  0, 33,  0,  0, 35, 33,  0,  0,  0,
-   33, 36,  0,  0,  0,  0,  0, 37, 38,  0,  0,  0,  0,  0,  0, 39,
-   40,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0, 43,  0, 44,
-    0,  0,  0, 45, 46,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0, 48,
-   49,  0,  0,  0,  0, 50,  0,  0,  0, 51,  0, 52,  0, 53,  0,  0,
-    0,  0, 54,  0,  0,  0,  0, 55,  0, 56,  0,  0,  0,  0, 57, 58,
-    0,  0,  0, 59, 60,  0,  0,  0,  0,  0,  0, 61, 52,  0, 62, 63,
-    0,  0, 64,  0,  0,  0, 65, 66,  0,  0,  0, 67,  0, 68, 69, 70,
-   71, 72,  1, 73,  0, 74, 75, 76,  0,  0, 77, 78,  0,  0,  0, 79,
-    0,  0,  1,  1,  0,  0, 80,  0,  0, 81,  0,  0,  0,  0, 77, 82,
-    0, 83,  0,  0,  0,  0,  0, 78, 84,  0, 85,  0, 52,  0,  1, 78,
-    0,  0, 86,  0,  0, 87,  0,  0,  0,  0,  0, 88, 57,  0,  0,  0,
-    0,  0,  0, 89, 90,  0,  0, 84,  0,  0, 33,  0,  0, 91,  0,  0,
-    0,  0, 92,  0,  0,  0,  0, 49,  0,  0, 93,  0,  0,  0,  0, 94,
-   95,  0,  0, 96,  0,  0, 97,  0,  0,  0, 98,  0,  0,  0, 99,  0,
-    0,  0,  0,100,101, 93,  0,  0,102,  0,  0,  0, 84,  0,  0,103,
-    0,  0,  0,104,105,  0,  0,106,107,  0,  0,  0,  0,  0,  0,108,
-    0,  0,109,  0,  0,  0,  0,110, 33,  0,111,112,113, 35,  0,  0,
-  114,  0,  0,  0,115,  0,  0,  0,  0,  0,  0,116,  0,  0,117,  0,
-    0,  0,  0,118, 88,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0, 52,
-  119,  0,  0,  0,  0,120,  0,  0,121,  0,  0,  0,  0,119,  0,  0,
-  122,  0,  0,  0,  0,  0,  0,123,  0,  0,  0,124,  0,  0,  0,125,
-    0,126,  0,  0,  0,  0,127,128,129,  0,130,  0,131,  0,  0,  0,
-  132,133,134,  0, 77,  0,  0,  0,  0,  0, 35,  0,  0,  0,135,  0,
-    0,  0,136,  0,  0,137,  0,  0,138,  0,  0,  0,  0,  0,  0,  0,
-    1,  1,  1,  1,  1,  2,  3,  4,  5,  6,  7,  4,  4,  8,  9, 10,
-    1, 11, 12, 13, 14, 15, 16, 17, 18,  1,  1,  1, 19,  1,  0,  0,
-   20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28, 29, 30,  0,  0,
-    1,  1, 31,  0,  0,  0, 32, 33, 34, 35,  1, 36, 37,  0,  0,  0,
-    0, 38,  1, 39, 14, 39, 40, 41, 42,  0,  0,  0, 43, 36, 44, 45,
-   21, 45, 46,  0,  0,  0, 19,  1, 21,  0,  0, 47,  0, 38, 48,  1,
-    1, 49, 49, 50,  0,  0, 51,  0,  0,  0, 52,  1,  0,  0, 38, 14,
-    4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,  0,  0,  0, 55,
-    0,  0,  0, 56, 57, 58,  0,  0,  0,  0,  0, 59,  0, 60,  0,  0,
-    0,  0, 61, 62,  0,  0, 63,  0,  0,  0, 64,  0,  0,  0, 65,  0,
-    0,  0, 66,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0, 69, 70,  0,
-   71, 72, 73, 74, 75, 76,  0,  0,  0, 77,  0,  0,  0, 78, 79,  0,
-    0,  0,  0, 47,  0,  0,  0, 49,  0, 80,  0,  0,  0, 62,  0,  0,
-   63,  0,  0, 81,  0,  0, 82,  0,  0,  0, 83,  0,  0, 19, 84,  0,
-   62,  0,  0,  0,  0, 49,  1, 85,  1, 52, 15, 86, 36, 10, 21, 87,
-    0, 55,  0,  0,  0,  0, 19, 10,  1,  0,  0,  0,  0,  0, 88,  0,
-    0, 89,  0,  0, 88,  0,  0,  0,  0, 78,  0,  0, 87,  9, 12,  4,
-   90,  8, 91, 47,  0, 58, 50,  0, 21,  1, 21, 92, 93,  1,  1,  1,
-    1, 94, 95, 96, 97,  1, 98, 58, 81, 99,100,  4, 58,  0,  0,  0,
-    0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0, 61,  0,  0,101,102,
-    0,  0,103,  0,  0,  1,  1, 50,  0,  0,  0, 38,  0, 63,  0,  0,
-    0,  0,  0, 62,  0,  0,104, 68, 61,  0,  0,  0, 78,  0,  0,  0,
-  105,106, 58, 38, 81,  0,  0,  0,  0,  0,  0,107,  1, 14,  4, 12,
-   84,  0,  0,  0,  0, 38, 87,  0,  0,  0,  0,108,  0,  0,109, 61,
-    0,110,  0,  0,  0,  1,  0,  0,  0,  0, 19, 58,  0,  0,  0, 51,
-    0,111, 14, 52,112, 41,  0,  0, 62,  0,  0, 61,  0,  0,113,  0,
-   87,  0,  0,  0, 61, 62,  0,  0, 62,  0, 89,  0,  0,113,  0,  0,
-    0,  0,114,  0,  0,  0, 78, 55,  0, 38,  1, 58,  1, 58,  0,  0,
-   63, 89,  0,  0,115,  0,  0,  0, 55,  0,  0,  0,  0,115,  0,  0,
-    0,  0, 61,  0,  0,  0,  0, 79,  0, 61,  0,  0,  0,  0, 56,  0,
-   89, 80,  0,  0, 79,  0,  0,  0,  8, 91,  0,  0,  1, 87,  0,  0,
-  116,  0,  0,  0,  0,  0,  0,117,  0,118,119,120,121,  0,104,  4,
-  122, 49, 23,  0,  0,  0, 38, 50, 38, 58,  0,  0,  1, 87,  1,  1,
-    1,  1, 39,  1, 48,105, 87,  0,  0,  0,  0,  1,  0,  0,  0,123,
-    4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,230,230,230,230,
-  230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
-  220,220,220,202,202,220,220,220,  1,  1,  1,  1,  1,220,220,220,
-  220,230,230,230,230,240,230,220,220,220,230,230,230,220,220,  0,
-  230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
-  234,234,233,230,  0,  0,  0,230,  0,220,230,230,230,230,220,230,
-  230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
-   14, 15, 16, 17, 18, 19, 19, 20, 21, 22,  0, 23,  0, 24, 25,  0,
-  230,220,  0, 18, 30, 31, 32,  0,  0,  0,  0, 27, 28, 29, 30, 31,
-   32, 33, 34,230,230,220,220,230,220,230,230,220, 35,  0,  0,  0,
-    0,  0,230,230,230,  0,  0,230,230,  0,220,230,230,220,  0,  0,
-    0, 36,  0,  0,230,220,230,230,220,220,230,220,220,230,220,230,
-  220,230,230,  0,  0,220,  0,  0,230,230,  0,230,  0,230,230,230,
-  230,230,  0,  0,  0,220,220,220,230,220,220,220,230,230,  0,220,
-   27, 28, 29,230,  7,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,
-  230,  0,  0,  0,  0,  0,230,  0,  0, 84, 91,  0,  0,  0,  0,  9,
-    9,  0,  0,  0,  0,  0,  9,  0,103,103,  9,  0,107,107,107,107,
-  118,118,  9,  0,122,122,122,122,220,220,  0,  0,  0,220,  0,220,
-    0,216,  0,  0,  0,129,130,  0,132,  0,  0,  0,  0,  0,130,130,
-  130,130,  0,  0,130,  0,230,230,  9,  0,230,230,  0,  0,220,  0,
-    0,  0,  0,  7,  0,  9,  9,  0,  9,  9,  0,  0,  0,230,  0,  0,
-    0,228,  0,  0,  0,222,230,220,220,  0,  0,  0,230,  0,  0,220,
-  230,220,  0,220,230,230,230,  0,  0,  0,  9,  9,  0,  0,  7,  0,
-  230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,202,230,230,230,
-  230,230,232,228,228,220,218,230,233,220,230,220,230,230,  1,  1,
-    1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,  0,  0,218,228,
-  232,222,224,224,  0,  8,  8,  0,  0,  0,  0,220,230,  0,230,230,
-  220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,
-    0,230,220,  0,  0,  0,220,220,  0,  0,230,220,  0,  9,  7,  0,
-    0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,  0,  0,  1,  0,
-    0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,
-  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 17,
-   17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,
-  129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
+   55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67,
+   67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67,
+   67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44,
+   67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41,
+   67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67,
+   67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55,
+   67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67,
+   79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44,
+  171,171,171,171,171,171,171,  0,  0,  0, 29, 21, 21, 21, 23, 21,
+   22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21,  9,  9,  9,
+    9, 22, 21, 18, 24, 16, 24,  5,  5,  5,  5, 22, 25, 18, 25,  0,
+   23, 23, 26, 21, 24, 26,  7, 20, 25,  1, 26, 24, 26, 25, 15, 15,
+   24, 15,  7, 19, 15, 21,  9, 25,  9,  5,  5, 25,  5,  9,  5,  7,
+    7,  7,  9,  8,  8,  5,  7,  5,  6,  6, 24, 24,  6, 24, 12, 12,
+    2,  2,  6,  5,  9, 21,  9,  2,  2,  9, 25,  9, 26, 12, 11, 11,
+    2,  6,  5, 21, 17,  2,  2, 26, 26, 23,  2, 12, 17, 12, 21, 12,
+   12, 21,  7,  2,  2,  7,  7, 21, 21,  2,  1,  1, 21, 23, 26, 26,
+    1, 21,  6,  7,  7, 12, 12,  7, 21,  7, 12,  1, 12,  6,  6, 12,
+   12, 26,  7, 26, 26,  7,  2,  1, 12,  2,  6,  2, 24,  7,  7,  6,
+    1, 12, 12, 10, 10, 10, 10, 12, 21,  6,  2, 10, 10,  2, 15, 26,
+   26,  2,  2, 21,  7, 10, 15,  7,  2, 23, 21, 26, 10,  7, 21, 15,
+   15,  2, 17,  7, 29,  7,  7, 22, 18,  2, 14, 14, 14,  7, 10, 21,
+   17, 21, 11, 12,  5,  2,  5,  6,  8,  8,  8, 24,  5, 24,  2, 24,
+    9, 24, 24,  2, 29, 29, 29,  1, 17, 17, 20, 19, 22, 20, 27, 28,
+    1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29,
+    1,  2, 15,  6, 18,  6, 23,  2, 12, 11,  9, 26, 26,  9, 26,  5,
+    5, 26, 14,  9,  5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25,
+   18, 22,  5, 12,  2,  5, 22, 21, 21, 22, 18, 17, 26,  6,  7, 14,
+   17, 22, 18, 18, 26, 14, 17,  6, 14,  6, 12, 24, 24,  6, 26, 15,
+    6, 21, 11, 21, 24,  9,  6,  9, 23, 26,  6, 10,  4,  4,  3,  3,
+    7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25,  2, 25, 24,  2, 15,
+   12, 15, 14,  2, 21, 14,  7, 15, 12, 17, 21,  1, 26, 10, 10,  1,
+   23, 15,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0, 10, 11, 12,
+   13,  0, 14,  0,  0,  0,  0,  0, 15,  0, 16,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,
+    0, 21, 22, 23,  0,  0,  0, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+   33, 34,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 35,  0, 36,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,
+    0,  0, 40, 41, 42,  0, 43,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  3,  0,  0,  0,  4,  5,
+    6,  7,  0,  8,  9, 10,  0, 11, 12, 13, 14, 15, 16, 17, 16, 18,
+   16, 19, 16, 19, 16, 19,  0, 19, 16, 20, 16, 19, 21, 19,  0, 22,
+   23, 24, 25, 26, 27, 28, 29, 30, 31,  0, 32,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 33,  0,  0,  0,  0,  0,  0, 34,  0,  0, 35,
+    0,  0, 36,  0, 37,  0,  0,  0, 38, 39, 40, 41, 42, 43, 44, 45,
+   46,  0,  0, 47,  0,  0,  0, 48,  0,  0,  0, 49,  0,  0,  0,  0,
+    0,  0,  0, 50,  0, 51,  0, 52, 53,  0, 54,  0,  0,  0,  0,  0,
+    0, 55, 56, 57,  0,  0,  0,  0, 58,  0,  0, 59, 60, 61, 62, 63,
+    0,  0, 64, 65,  0,  0,  0, 66,  0,  0,  0,  0, 67,  0,  0,  0,
+   68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 69,
+    0,  0,  0, 70,  0, 71,  0,  0, 72,  0,  0, 73,  0,  0,  0,  0,
+    0,  0,  0,  0, 74,  0,  0,  0,  0,  0, 75, 76,  0, 77, 78,  0,
+    0, 79, 80,  0, 81, 62,  0, 82, 83,  0,  0, 84, 85, 86,  0,  0,
+    0, 87,  0, 88,  0,  0, 51, 89, 51,  0, 90,  0, 91,  0,  0,  0,
+   80,  0,  0,  0, 92, 93,  0, 94, 95, 96, 97,  0,  0,  0,  0,  0,
+   51,  0,  0,  0,  0, 98, 99,  0,  0,  0,  0,  0,  0,100,  0,  0,
+    0,  0,  0,101,102,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,103,
+    0,  0,104,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,106,  0,
+    0,107,  0,  0,  0,  0,  0,  0,108,  0,109,  0,102,  0,  0,  0,
+    0,  0,110,111,  0,  0,  0,  0,  0,  0,  0,112,  0,  0,  0,  0,
+    0,  0,  0,113,  0,114,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  0,  8,  0,  0,  0,  0,  9, 10, 11, 12,  0,  0,  0,
+    0, 13,  0,  0, 14, 15,  0, 16,  0, 17, 18,  0,  0, 19,  0, 20,
+   21,  0,  0,  0,  0,  0, 22, 23,  0, 24, 25,  0,  0, 26,  0,  0,
+    0, 27,  0,  0, 28, 29, 30, 31,  0,  0,  0, 32, 33, 34,  0,  0,
+   33,  0,  0, 35, 33,  0,  0,  0, 33, 36,  0,  0,  0,  0,  0, 37,
+   38,  0,  0,  0,  0,  0,  0, 39, 40,  0,  0,  0,  0,  0,  0, 41,
+   42,  0,  0,  0,  0, 43,  0, 44,  0,  0,  0, 45, 46,  0,  0,  0,
+   47,  0,  0,  0,  0,  0,  0, 48, 49,  0,  0,  0,  0, 50,  0,  0,
+    0, 51,  0, 52,  0, 53,  0,  0,  0,  0, 54,  0,  0,  0,  0, 55,
+    0, 56,  0,  0,  0,  0, 57, 58,  0,  0,  0, 59, 60,  0,  0,  0,
+    0,  0,  0, 61, 52,  0, 62, 63,  0,  0, 64,  0,  0,  0, 65, 66,
+    0,  0,  0, 67,  0, 68, 69, 70, 71, 72,  1, 73,  0, 74, 75, 76,
+    0,  0, 77, 78,  0,  0,  0, 79,  0,  0,  1,  1,  0,  0, 80,  0,
+    0, 81,  0,  0,  0,  0, 77, 82,  0, 83,  0,  0,  0,  0,  0, 78,
+   84,  0, 85,  0, 52,  0,  1, 78,  0,  0, 86,  0,  0, 87,  0,  0,
+    0,  0,  0, 88, 57,  0,  0,  0,  0,  0,  0, 89, 90,  0,  0, 84,
+    0,  0, 33,  0,  0, 91,  0,  0,  0,  0, 92,  0,  0,  0,  0, 49,
+    0,  0, 93,  0,  0,  0,  0, 94, 95,  0,  0, 96,  0,  0, 97,  0,
+    0,  0, 98,  0,  0,  0, 99,  0,  0,  0,  0,100,101, 93,  0,  0,
+  102,  0,  0,  0, 84,  0,  0,103,  0,  0,  0,104,105,  0,  0,106,
+  107,  0,  0,  0,  0,  0,  0,108,  0,  0,109,  0,  0,  0,  0,110,
+   33,  0,111,112,113, 35,  0,  0,114,  0,  0,  0,115,  0,  0,  0,
+    0,  0,  0,116,  0,  0,117,  0,  0,  0,  0,118, 88,  0,  0,  0,
+    0,  0, 57,  0,  0,  0,  0, 52,119,  0,  0,  0,  0,120,  0,  0,
+  121,  0,  0,  0,  0,119,  0,  0,122,  0,  0,  0,  0,  0,  0,123,
+    0,  0,  0,124,  0,  0,  0,125,  0,126,  0,  0,  0,  0,127,128,
+  129,  0,130,  0,131,  0,  0,  0,132,133,134,  0, 77,  0,  0,  0,
+    0,  0, 35,  0,  0,  0,135,  0,  0,  0,136,  0,  0,137,  0,  0,
+  138,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  3,  4,
+    5,  6,  7,  4,  4,  8,  9, 10,  1, 11, 12, 13, 14, 15, 16, 17,
+   18,  1,  1,  1, 19,  1,  0,  0, 20, 21, 22,  1, 23,  4, 21, 24,
+   25, 26, 27, 28, 29, 30,  0,  0,  1,  1, 31,  0,  0,  0, 32, 33,
+   34, 35,  1, 36, 37,  0,  0,  0,  0, 38,  1, 39, 14, 39, 40, 41,
+   42,  0,  0,  0, 43, 36, 44, 45, 21, 45, 46,  0,  0,  0, 19,  1,
+   21,  0,  0, 47,  0, 38, 48,  1,  1, 49, 49, 50,  0,  0, 51,  0,
+    0,  0, 52,  1,  0,  0, 38, 14,  4,  1,  1,  1, 53, 21, 43, 52,
+   54, 21, 35,  1,  0,  0,  0, 55,  0,  0,  0, 56, 57, 58,  0,  0,
+    0,  0,  0, 59,  0, 60,  0,  0,  0,  0, 61, 62,  0,  0, 63,  0,
+    0,  0, 64,  0,  0,  0, 65,  0,  0,  0, 66,  0,  0,  0, 67,  0,
+    0,  0, 68,  0,  0, 69, 70,  0, 71, 72, 73, 74, 75, 76,  0,  0,
+    0, 77,  0,  0,  0, 78, 79,  0,  0,  0,  0, 47,  0,  0,  0, 49,
+    0, 80,  0,  0,  0, 62,  0,  0, 63,  0,  0, 81,  0,  0, 82,  0,
+    0,  0, 83,  0,  0, 19, 84,  0, 62,  0,  0,  0,  0, 49,  1, 85,
+    1, 52, 15, 86, 36, 10, 21, 87,  0, 55,  0,  0,  0,  0, 19, 10,
+    1,  0,  0,  0,  0,  0, 88,  0,  0, 89,  0,  0, 88,  0,  0,  0,
+    0, 78,  0,  0, 87,  9, 12,  4, 90,  8, 91, 47,  0, 58, 50,  0,
+   21,  1, 21, 92, 93,  1,  1,  1,  1, 94, 95, 96, 97,  1, 98, 58,
+   81, 99,100,  4, 58,  0,  0,  0,  0,  0,  0, 19, 50,  0,  0,  0,
+    0,  0,  0, 61,  0,  0,101,102,  0,  0,103,  0,  0,  1,  1, 50,
+    0,  0,  0, 38,  0, 63,  0,  0,  0,  0,  0, 62,  0,  0,104, 68,
+   61,  0,  0,  0, 78,  0,  0,  0,105,106, 58, 38, 81,  0,  0,  0,
+    0,  0,  0,107,  1, 14,  4, 12, 84,  0,  0,  0,  0, 38, 87,  0,
+    0,  0,  0,108,  0,  0,109, 61,  0,110,  0,  0,  0,  1,  0,  0,
+    0,  0, 19, 58,  0,  0,  0, 51,  0,111, 14, 52,112, 41,  0,  0,
+   62,  0,  0, 61,  0,  0,113,  0, 87,  0,  0,  0, 61, 62,  0,  0,
+   62,  0, 89,  0,  0,113,  0,  0,  0,  0,114,  0,  0,  0, 78, 55,
+    0, 38,  1, 58,  1, 58,  0,  0, 63, 89,  0,  0,115,  0,  0,  0,
+   55,  0,  0,  0,  0,115,  0,  0,  0,  0, 61,  0,  0,  0,  0, 79,
+    0, 61,  0,  0,  0,  0, 56,  0, 89, 80,  0,  0, 79,  0,  0,  0,
+    8, 91,  0,  0,  1, 87,  0,  0,116,  0,  0,  0,  0,  0,  0,117,
+    0,118,119,120,121,  0,104,  4,122, 49, 23,  0,  0,  0, 38, 50,
+   38, 58,  0,  0,  1, 87,  1,  1,  1,  1, 39,  1, 48,105, 87,  0,
+    0,  0,  0,  1,  0,  0,  0,123,  4,122,  0,  0,  0,  1,124,  0,
+    0,  0,  0,  0,230,230,230,230,230,232,220,220,220,220,232,216,
+  220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,
+    1,  1,  1,  1,  1,220,220,220,220,230,230,230,230,240,230,220,
+  220,220,230,230,230,220,220,  0,230,230,230,220,220,220,220,230,
+  232,220,220,230,233,234,234,233,234,234,233,230,  0,  0,  0,230,
+    0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220,
+  230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
+   21, 22,  0, 23,  0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,
+    0,  0,  0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,
+  220,230,230,220, 35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,
+  230,  0,220,230,230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,
+  220,220,230,220,220,230,220,230,220,230,230,  0,  0,220,  0,  0,
+  230,230,  0,230,  0,230,230,230,230,230,  0,  0,  0,220,220,220,
+  230,220,220,220,230,230,  0,220, 27, 28, 29,230,  7,  0,  0,  0,
+    0,  9,  0,  0,  0,230,220,230,230,  0,  0,  0,  0,  0,230,  0,
+    0, 84, 91,  0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  9,  0,
+  103,103,  9,  0,107,107,107,107,118,118,  9,  0,122,122,122,122,
+  220,220,  0,  0,  0,220,  0,220,  0,216,  0,  0,  0,129,130,  0,
+  132,  0,  0,  0,  0,  0,130,130,130,130,  0,  0,130,  0,230,230,
+    9,  0,230,230,  0,  0,220,  0,  0,  0,  0,  7,  0,  9,  9,  0,
+    9,  9,  0,  0,  0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,
+  220,  0,  0,  0,230,  0,  0,220,230,220,  0,220,230,230,230,  0,
+    0,  0,  9,  9,  0,  0,  7,  0,230,  0,  1,  1,  1,  0,  0,  0,
+  230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230,
+  233,220,230,220,230,230,  1,  1,  1,  1,  1,230,  0,  1,  1,230,
+  220,230,  1,  1,  0,  0,218,228,232,222,224,224,  0,  8,  8,  0,
+    0,  0,  0,220,230,  0,230,230,220,  0,  0,230,  0,  0, 26,  0,
+    0,220,  0,230,230,  1,220,  0,  0,230,220,  0,  0,  0,220,220,
+    0,  0,230,220,  0,  9,  7,  0,  0,  7,  9,  0,  0,  0,  9,  7,
+    6,  6,  0,  0,  0,  0,  1,  0,  0,216,216,  1,  1,  1,  0,  0,
+    0,226,216,216,216,216,216,  0,220,220,220,  0,232,232,220,230,
+  230,230,  7,  0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19,
+   17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237,  0,  1,  2,  2,
-    0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  6,  7,  8,
-    9,  0,  0,  0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 20,  0,  0, 21, 22,  0,  0,  0,  0,
-   23, 24, 25, 26,  0, 27,  0, 28, 29, 30, 31, 32,  0,  0,  0,  0,
-    0,  0,  0, 33, 34, 35, 36,  0,  0,  0,  0,  0, 37,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,  1,  2, 40, 41,
-    0,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,
-    0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  5,  0,
-    0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  7,  1,  0,  0,  0,  0,
-    0,  0,  8,  9,  0,  0,  0,  0,  0,  0, 10,  0,  0, 10,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, 10,
-    0,  0,  0,  0,  0,  0, 11, 12,  0, 13,  0, 14, 15, 16,  0,  0,
-    0,  0,  0,  1, 17, 18,  0, 19,  7,  1,  0,  0,  0, 20, 20,  7,
-   20, 20, 20, 20, 20, 20, 20,  8, 21,  0, 22,  0,  7, 23, 24,  0,
-   20, 20, 25,  0,  0,  0, 26, 27,  1,  7, 20, 20, 20, 20, 20,  1,
-   28, 29, 30, 31,  0,  0, 20,  0,  0,  0,  0,  0,  0,  0, 10,  0,
-    0,  0,  0,  0,  0,  0, 20, 20, 20,  1,  0,  0,  8, 21, 32,  4,
-    0, 10,  0, 33,  7, 20, 20, 20,  0,  0,  0,  0,  8, 34, 34, 35,
-   36, 34, 37,  0, 38,  1, 20, 20,  0,  0, 39,  0,  1,  1,  0,  8,
-   21,  1, 20,  0,  0,  0,  1,  0,  0, 40,  1,  1,  0,  0,  8, 21,
-    0,  1,  0,  1,  0,  1,  0,  0,  0,  0, 26, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 21,  7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 21,  0, 42, 43, 44,  0, 45,  0,  8, 21,  0,  0,  0,  0,  0,
-    0,  0,  0, 46,  7,  1, 10,  1,  0,  0,  0,  1, 20, 20,  1,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0, 26, 34,  9,  0,  0, 20, 20,
-    1, 20, 20,  0,  0,  0,  0,  0,  0,  0, 26, 21,  0,  1,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 47, 48,  0,  0,  0,
-    0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7,  9, 10, 11, 11, 11, 11, 12, 13,
-   13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13,
-   13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32,
-   33, 34, 35, 36,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7, 37,  7, 38, 39,  7, 40,  7,  7,
-    7, 41, 13, 42,  7,  7, 43,  7, 44, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17,237,  0,  1,  2,  2,  0,  3,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    5,  0,  0,  0,  0,  6,  7,  8,  9,  0,  0,  0, 10, 11, 12, 13,
+   14, 15, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,
+    0,  0, 21, 22,  0,  0,  0,  0, 23, 24, 25, 26,  0, 27,  0, 28,
+   29, 30, 31, 32,  0,  0,  0,  0,  0,  0,  0, 33, 34, 35, 36,  0,
+    0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,
+    0,  0,  0,  0,  1,  2, 40, 41,  0,  1,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  2,  0,  0,  0,  0,
+    0,  0,  3,  4,  0,  0,  5,  0,  0,  0,  6,  0,  0,  0,  0,  0,
+    0,  0,  7,  1,  0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,  0,
+    0,  0, 10,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 10,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0, 11, 12,
+    0, 13,  0, 14, 15, 16,  0,  0,  0,  0,  0,  1, 17, 18,  0, 19,
+    7,  1,  0,  0,  0, 20, 20,  7, 20, 20, 20, 20, 20, 20, 20,  8,
+   21,  0, 22,  0,  7, 23, 24,  0, 20, 20, 25,  0,  0,  0, 26, 27,
+    1,  7, 20, 20, 20, 20, 20,  1, 28, 29, 30, 31,  0,  0, 20,  0,
+    0,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0, 20, 20,
+   20,  1,  0,  0,  8, 21, 32,  4,  0, 10,  0, 33,  7, 20, 20, 20,
+    0,  0,  0,  0,  8, 34, 34, 35, 36, 34, 37,  0, 38,  1, 20, 20,
+    0,  0, 39,  0,  1,  1,  0,  8, 21,  1, 20,  0,  0,  0,  1,  0,
+    0, 40,  1,  1,  0,  0,  8, 21,  0,  1,  0,  1,  0,  1,  0,  0,
+    0,  0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  7, 20, 41,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  0, 42, 43, 44,  0, 45,
+    0,  8, 21,  0,  0,  0,  0,  0,  0,  0,  0, 46,  7,  1, 10,  1,
+    0,  0,  0,  1, 20, 20,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 26, 34,  9,  0,  0, 20, 20,  1, 20, 20,  0,  0,  0,  0,  0,
+    0,  0, 26, 21,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  3, 47, 48,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,
+    4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
+   19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
+   13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   37,  7, 38, 39,  7, 40,  7,  7,  7, 41, 13, 42,  7,  7, 43,  7,
+   44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -1716,201 +1716,202 @@
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 45,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,
-    8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
-   37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
-   51, 52,  2,  2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
-   59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
-   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45,  0,  0,  1,
+    2,  2,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
+   43, 44, 45, 46, 47, 48, 49, 50, 51, 52,  2,  2, 53, 54, 55, 56,
+   57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
+   59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+   74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81,
-   82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32,
-   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
+   80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
+   89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,
-  102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116,
-  117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131,
-  132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145,
-   96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158,
-  159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164,
-  167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171,
-  171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96,
-   96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185,
-  186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204,
-  205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96,
-   96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215,
-   96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221,
-  222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59,
-   59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
+  110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
+  124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
+  139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
+  152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
+  164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
+  169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
+  173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
+  182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+  182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
+  182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
+  190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
+  198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
+  208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
+  213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
+  219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
+   59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
+   59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96,
-   96, 96, 96, 96, 96, 96,245, 96,246,247,  0,  1,  2,  2,  0,  1,
-    2,  2,  2,  3,  4,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-   19,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19, 19, 19,  0, 19,  0,  0,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19,  0,  0,  0,  0,  0, 26, 26,  0,  0,  0,  0,  1,  1,
-    1,  1,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
-    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
-    9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    2,  9,  9,  9,  9,  9,  9,  9, 55, 55, 55, 55, 55, 55, 55, 55,
-   55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
-    6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,
-    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  4,  4,
-    4,  2,  2,  4,  4,  4,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-   14, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2, 14, 14,
-   14,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14,  2,  2,  2,  3,  3,
-    3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  0,  0,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  1,
-    1,  1,  1,  1,  3,  3,  1,  3,  3,  3,  3,  3,  3,  3, 37, 37,
-   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
-   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
-    2,  2,  2,  2,  2,  2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-   64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
-   90, 90, 90, 90,  2,  2, 90, 90, 90, 90, 90, 90, 90,  2, 95, 95,
-   95, 95, 95, 95, 95, 95, 95, 95, 95, 95,  2,  2, 95,  2, 37, 37,
-   37,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,
-    2,  2,  2,  2,  2,  2,  3,  3,  0,  3,  3,  3,  3,  3,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  7,  7,
-    7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,
-    5,  5,  5,  2,  2,  5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  2,
-    5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  5,  2,
-    2,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,  5,  2,  2,
-    2,  2,  5,  5,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  2,  2, 11, 11, 11,  2, 11, 11, 11, 11, 11,
-   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11, 11,
-   11, 11, 11, 11, 11, 11, 11,  2, 11, 11, 11, 11, 11, 11, 11,  2,
-   11, 11,  2, 11, 11,  2, 11, 11,  2,  2, 11,  2, 11, 11, 11,  2,
-    2, 11, 11, 11,  2,  2,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11,
-   11, 11, 11,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,
-   11, 11, 11, 11, 11,  2,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10,
-   10, 10, 10, 10,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,
-   10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,  2,
-   10, 10,  2, 10, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10, 10, 10,
-    2, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,  2,  2, 10, 10,
-   10, 10,  2,  2, 10, 10, 10, 10,  2,  2,  2,  2,  2,  2,  2, 10,
-   10, 10, 10, 10, 10, 10,  2, 21, 21, 21,  2, 21, 21, 21, 21, 21,
-   21, 21, 21,  2,  2, 21, 21,  2,  2, 21, 21, 21, 21, 21, 21, 21,
-   21, 21, 21, 21, 21, 21, 21,  2, 21, 21, 21, 21, 21, 21, 21,  2,
-   21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21, 21, 21,  2,
-    2, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2, 21, 21, 21,  2,  2,
-    2,  2, 21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,  2,
-   22, 22,  2, 22, 22, 22, 22, 22, 22,  2,  2,  2, 22, 22, 22,  2,
-   22, 22, 22, 22,  2,  2,  2, 22, 22,  2, 22,  2, 22, 22,  2,  2,
-    2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-    2,  2,  2,  2, 22, 22, 22,  2,  2,  2,  2,  2,  2, 22,  2,  2,
-    2,  2,  2,  2, 22, 22, 22, 22, 22,  2,  2,  2,  2,  2, 23, 23,
-   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  2, 23, 23, 23,  2,
-   23, 23, 23, 23, 23, 23, 23, 23,  2,  2, 23, 23, 23, 23, 23,  2,
-   23, 23, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 23,  2, 23, 23,
-   23,  2,  2, 23,  2,  2, 23, 23, 23, 23,  2,  2, 23, 23,  2,  2,
-    2,  2,  2,  2,  2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16, 16,  2, 16, 16, 16,  2, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16,  2, 16, 16, 16, 16, 16,  2,  2, 16, 16, 16, 16, 16,  2,
-   16, 16, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16, 16,  2, 16, 16,
-   16, 16,  2,  2, 16, 16,  2, 16, 16, 16,  2,  2,  2,  2, 20, 20,
-   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2, 20, 20, 20,  2,
-   20, 20, 20, 20, 20, 20,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20,
-   20, 20,  2,  2, 20, 20,  2, 36, 36, 36,  2, 36, 36, 36, 36, 36,
-   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,
-   36, 36, 36, 36, 36, 36, 36, 36,  2, 36, 36, 36, 36, 36, 36, 36,
-   36, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36, 36,
-   36, 36, 36,  2, 36,  2,  2,  2,  2,  2,  2,  2, 36, 36,  2,  2,
-   36, 36, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0, 24, 24,
-   24, 24,  2,  2,  2,  2,  2, 18, 18,  2, 18,  2, 18, 18, 18, 18,
-   18,  2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-   18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2,  2, 18, 18,
-   18, 18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2, 18, 18,
-    2,  2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25,  2, 25,
-   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  2,  2,  2, 25, 25,
-   25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25,  0,  0,  0,  0, 25,
-   25,  2,  2,  2,  2,  2, 33, 33, 33, 33, 33, 33, 33, 33,  8,  8,
-    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  2,  8,  2,  2,
-    2,  2,  2,  8,  2,  2,  8,  8,  8,  0,  8,  8,  8,  8, 12, 12,
-   12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30,  2,
-   30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,  2, 30, 30,
-   30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30,  2,  2,  2, 30, 30,
-    2,  2,  2,  2,  2,  2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-   29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34,
-   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
-   35, 35, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,
-    2,  2,  2,  2,  2,  2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-   45, 45, 45, 45,  2,  2,  2,  2,  2,  2,  2,  2,  2, 45, 44, 44,
-   44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43,
-   43, 43, 43, 43, 43, 43, 43, 43, 43, 43,  2,  2,  2,  2, 46, 46,
-   46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,  2, 46, 46, 46,  2,
-   46, 46,  2,  2,  2,  2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-   31, 31, 31, 31,  2,  2, 31, 31,  2,  2,  2,  2,  2,  2, 32, 32,
-    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    2,  2,  2,  2,  2,  2, 32,  2,  2,  2,  2,  2,  2,  2, 32, 32,
-   32,  2,  2,  2,  2,  2, 28, 28, 28, 28, 28, 28,  2,  2, 48, 48,
-   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,  2, 48, 48,
-   48, 48,  2,  2,  2,  2, 48,  2,  2,  2, 48, 48, 48, 48, 52, 52,
-   52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,  2,  2, 52, 52,
-   52, 52, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-   58, 58,  2,  2,  2,  2, 58, 58,  2,  2,  2,  2,  2,  2, 58, 58,
-   58,  2,  2,  2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
-   54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-   91, 91, 91, 91, 91,  2, 91, 91, 91, 91, 91,  2,  2, 91, 91, 91,
-    2,  2,  2,  2,  2,  2, 91, 91, 91, 91, 91, 91,  2,  2,  1,  1,
-    1,  1,  1,  1,  1,  2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
-   62, 62, 62,  2,  2,  2, 62, 62, 62, 62, 62, 62, 62,  2, 76, 76,
-   76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
-   93, 93,  2,  2,  2,  2,  2,  2,  2,  2, 93, 93, 93, 93, 70, 70,
-   70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 70, 70, 70, 70,
-    2,  2,  2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73,  6,  2,
-    2,  2,  2,  2,  2,  2,  8,  8,  8,  2,  2,  8,  8,  8,  1,  1,
-    1,  0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  0,
-    0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  1,
-    0,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,
-    9,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9,
-   19, 19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19, 19,  6, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,
-    9,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  2,  9,  9,  9,
-    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,
-    9,  9,  2,  9,  9,  9,  2,  2,  9,  9,  9,  2,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  2,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,
-    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  0,  2, 19, 19,
-   19, 19, 19,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,
-   19, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0, 19,  0,
-    0,  0,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  2, 27, 27,
-   27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,
-    0,  0,  0,  0,  2,  0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55,
-   55, 55,  2,  2,  2,  2,  2, 55, 55, 55, 55, 55, 55, 55, 61, 61,
-   61, 61, 61, 61, 61, 61,  2,  2,  2,  2,  2,  2,  2, 61, 61,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,  2, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13, 13, 13, 13, 13,
-   13, 13,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13,  2,  2,  0,  0,
-    0,  0,  2,  2,  2,  2,  0,  0,  0,  0,  0, 13,  0, 13,  0, 13,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
+   70, 70, 70, 70, 70,241, 70, 70, 70, 70,242, 96, 96, 96, 70, 70,
+   70, 70,243, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+   70, 70, 70, 70,244, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70, 70,245, 96, 96, 96, 96, 96, 96, 96, 96,246, 96,
+  247,248,  0,  1,  2,  2,  0,  1,  2,  2,  2,  3,  4,  5,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0,  0,  0,
+   19,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19,  0, 19,  0,
+    0,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0,
+   26, 26,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  9,  9,
+    9,  9,  0,  9,  9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,
+    2,  2,  9,  0,  9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,
+   55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,  6,  6,
+    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  1,  1,  6,  2,  4,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  2,  4,  4,  4,  2,  2,  4,  4,  4,  2, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  2,  2,
+    2,  2,  2,  2,  2,  2, 14, 14, 14,  2,  2,  2,  2, 14, 14, 14,
+   14, 14, 14,  2,  2,  2,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,
+    3,  3,  0,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  0,  3,  3,  3,  0,  0,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  3,  3,  1,  3,
+    3,  3,  3,  3,  3,  3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+   37, 37, 37, 37,  2, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38,
+   38, 38, 38, 38, 38, 38, 38, 38,  2,  2,  2,  2,  2,  2, 64, 64,
+   64, 64, 64, 64, 64, 64, 64, 64, 64,  2,  2, 64, 64, 64, 90, 90,
+   90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90,
+   90, 90, 90, 90, 90,  2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
+   95, 95,  2,  2, 95,  2, 37, 37, 37,  2,  2,  2,  2,  2,  3,  3,
+    3,  3,  3,  3,  3,  2,  3,  3,  2,  2,  2,  2,  2,  2,  3,  3,
+    0,  3,  3,  3,  3,  3,  7,  7,  7,  7,  7,  7,  7,  7,  7,  1,
+    1,  1,  1,  7,  7,  7,  7,  7,  7,  7,  0,  0,  7,  7,  5,  5,
+    5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  5,  5,  2,
+    2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,
+    5,  5,  5,  5,  5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,
+    2,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  2,  2,  2,
+    2,  2,  2,  2,  2,  5,  2,  2,  2,  2,  5,  5,  2,  5,  5,  5,
+    5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2, 11,
+   11, 11,  2, 11, 11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,
+    2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,
+   11, 11, 11, 11, 11, 11, 11,  2, 11, 11,  2, 11, 11,  2, 11, 11,
+    2,  2, 11,  2, 11, 11, 11,  2,  2, 11, 11, 11,  2,  2,  2, 11,
+    2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,  2, 11,  2,  2,  2,
+    2,  2,  2,  2, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,  2, 10,
+   10, 10,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,
+    2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2,
+   10, 10, 10, 10, 10, 10, 10,  2, 10, 10,  2, 10, 10, 10, 10, 10,
+    2,  2, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,  2,  2, 10,  2,
+    2,  2,  2,  2,  2,  2, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10,
+    2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10,  2, 21,
+   21, 21,  2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,
+    2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,
+   21, 21, 21, 21, 21, 21, 21,  2, 21, 21,  2, 21, 21, 21, 21, 21,
+    2,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21,  2,  2,  2,  2,
+    2,  2,  2, 21, 21, 21,  2,  2,  2,  2, 21, 21,  2, 21, 21, 21,
+   21, 21,  2,  2, 21, 21,  2,  2, 22, 22,  2, 22, 22, 22, 22, 22,
+   22,  2,  2,  2, 22, 22, 22,  2, 22, 22, 22, 22,  2,  2,  2, 22,
+   22,  2, 22,  2, 22, 22,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22,
+   22, 22, 22, 22, 22, 22, 22, 22,  2,  2,  2,  2, 22, 22, 22,  2,
+    2,  2,  2,  2,  2, 22,  2,  2,  2,  2,  2,  2, 22, 22, 22, 22,
+   22,  2,  2,  2,  2,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+   23, 23, 23,  2, 23, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23,
+    2,  2, 23, 23, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2,  2,
+    2,  2,  2, 23, 23,  2, 23, 23, 23,  2,  2, 23,  2,  2, 23, 23,
+   23, 23,  2,  2, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 16, 16,
+   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16,  2,
+   16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16, 16,
+    2,  2, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16,  2,  2,  2,  2,
+    2,  2,  2, 16, 16,  2, 16, 16, 16, 16,  2,  2, 16, 16,  2, 16,
+   16, 16,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+   20, 20, 20,  2, 20, 20, 20,  2, 20, 20, 20, 20, 20, 20,  2,  2,
+    2,  2, 20, 20, 20, 20, 20, 20, 20, 20,  2,  2, 20, 20,  2, 36,
+   36, 36,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36, 36,
+    2, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,  2,
+   36,  2,  2,  2,  2, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,
+    2,  2,  2,  2, 36, 36,  2,  2, 36, 36, 36,  2,  2,  2,  2, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24,  2,  2,  2,  2,  0, 24, 24, 24, 24,  2,  2,  2,  2,  2, 18,
+   18,  2, 18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18, 18, 18,
+   18, 18, 18, 18, 18, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18,
+   18, 18, 18, 18,  2,  2, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18,
+   18, 18, 18, 18, 18,  2, 18, 18,  2,  2, 18, 18, 18, 18, 25, 25,
+   25, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25,  2,  2,  2, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25,
+   25, 25, 25,  0,  0,  0,  0, 25, 25,  2,  2,  2,  2,  2, 33, 33,
+   33, 33, 33, 33, 33, 33,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+    8,  8,  8,  8,  2,  8,  2,  2,  2,  2,  2,  8,  2,  2,  8,  8,
+    8,  0,  8,  8,  8,  8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30,
+   30, 30, 30, 30, 30, 30, 30,  2, 30, 30, 30, 30,  2,  2, 30, 30,
+   30, 30, 30, 30, 30,  2, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30,
+   30, 30, 30,  2,  2,  2, 30, 30,  2,  2,  2,  2,  2,  2, 29, 29,
+   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28,
+   28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34,  2,  2,  2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35,  0,  0,  0, 35, 35, 35,  2,  2,  2,  2,  2,  2,  2, 45, 45,
+   45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,  2,  2,  2,  2,
+    2,  2,  2,  2,  2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+   44, 44, 44,  0,  0,  2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+   43, 43,  2,  2,  2,  2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+   46, 46, 46,  2, 46, 46, 46,  2, 46, 46,  2,  2,  2,  2, 31, 31,
+   31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,  2,  2, 31, 31,
+    2,  2,  2,  2,  2,  2, 32, 32,  0,  0, 32,  0, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32,  2,  2,  2,  2,  2,  2, 32,  2,
+    2,  2,  2,  2,  2,  2, 32, 32, 32,  2,  2,  2,  2,  2, 28, 28,
+   28, 28, 28, 28,  2,  2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+   48, 48, 48, 48, 48,  2, 48, 48, 48, 48,  2,  2,  2,  2, 48,  2,
+    2,  2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+   52, 52, 52, 52,  2,  2, 52, 52, 52, 52, 52,  2,  2,  2, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58,  2,  2,  2,  2, 58, 58,
+    2,  2,  2,  2,  2,  2, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54,
+   54, 54, 54, 54, 54, 54, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,  2, 91, 91,
+   91, 91, 91,  2,  2, 91, 91, 91,  2,  2,  2,  2,  2,  2, 91, 91,
+   91, 91, 91, 91,  2,  2,  1,  1,  1,  1,  1,  1,  1,  2, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,  2,  2,  2, 62, 62,
+   62, 62, 62, 62, 62,  2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93,
+   93, 93, 93, 93, 93, 93, 93, 93, 93, 93,  2,  2,  2,  2,  2,  2,
+    2,  2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70,  2,  2,
+    2, 70, 70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73,
+   73, 73, 73, 73, 73, 73,  6,  2,  2,  2,  2,  2,  2,  2,  8,  8,
+    8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  1,  1,  1,  1,  0,
+    1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0,
+    0,  0,  1,  0,  0,  0,  1,  1,  0,  2,  2,  2,  2,  2, 19, 19,
+   19, 19, 19, 19,  9,  9,  9,  9,  9,  6, 19, 19, 19, 19, 19, 19,
+   19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19,  9,  9,  9,  9,
+    9, 19, 19, 19, 19, 19,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  9,  9,  9,  9,  9,  9,  9,  2,  2,  2,  9,
+    2,  9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  9,
+    9,  9,  2,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  2,  2,
+    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  0,  0,
+    0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0, 19,
+    2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,
+    0,  0,  0,  0,  0,  2, 19, 19, 19, 19, 19,  2,  2,  2,  0,  2,
+    2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2,  2,  0,  0,
+    0,  0,  0,  0,  9,  0,  0,  0, 19, 19,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 19,  0, 19,  0,  0,  0,  2,  2,  2,  2,  0,  0,
+    0,  2,  2,  2,  2,  2, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,
+    0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0, 56, 56,
+   56, 56, 56, 56, 56, 56, 55, 55, 55, 55,  2,  2,  2,  2,  2, 55,
+   55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61,  2,  2,
+    2,  2,  2,  2,  2, 61, 61,  2,  2,  2,  2,  2,  2,  2,  0,  0,
+    0,  0,  0,  0,  2,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    2, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2, 13, 13,
+   13, 13, 13, 13,  2,  2,  0,  0,  0,  0,  0, 13,  0, 13,  0, 13,
    13, 13, 13, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12, 13, 13,
    13, 13,  0,  0,  0,  0,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  1,
     1,  0,  0, 15, 15, 15,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17,  0,  0, 17, 17, 17,  2,  2,
     2,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2, 12,
-   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2,  0,  0,
+    0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0, 12, 12,
    12, 12, 12, 12, 12,  0, 17, 17, 17, 17, 17, 17, 17,  0, 39, 39,
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39,
    39, 39, 39, 39, 39,  2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77,
@@ -2190,7 +2191,7 @@
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
 };
 static const uint16_t
-_hb_ucd_u16[9320] =
+_hb_ucd_u16[9344] =
 {
      0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
     13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
@@ -2233,9 +2234,9 @@
    209, 306, 209, 209, 209, 209, 209, 209,   9,   9,   9,  11,  11,  11, 307, 308,
     13,  13,  13,  13,  13,  13, 309, 310,  11,  11, 311,  48,  48,  48, 312, 313,
     48, 314, 315, 315, 315, 315,  32,  32, 316, 317, 318, 319, 320, 321, 140, 140,
-   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
-   326, 327, 328, 329, 136,  48,  48,  48,  48, 330, 178,  48,  48,  48,  48, 331,
-   332,  48,  48, 136,  48,  48,  48,  48, 200, 333,  48,  48, 209, 209, 323,  48,
+   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209,
+   325, 326, 327, 328, 136,  48,  48,  48,  48, 329, 178,  48,  48,  48,  48, 330,
+   331,  48,  48, 136,  48,  48,  48,  48, 200, 332,  48,  48, 209, 209, 333,  48,
    209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
     48,  48,  48,  48, 209, 209, 209, 209,  48, 338,  48,  48,  48,  48,  48,  48,
    151, 209, 209, 209, 287,  48,  48, 229, 339,  48, 340, 140,  13,  13, 341, 342,
@@ -2306,475 +2307,476 @@
      9,   9, 607,  11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
    271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
    659,  48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
-   209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
-   670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
-   673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
-   209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
-   209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
-   679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
-   674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
+   209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324,
+   671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209,
+   674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677,
+   209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679,
+   209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209,
+   680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426,
+   675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192,
     48,  48,  48,  48,  48,  48, 140, 140,  48,  48,  48, 207,  48,  48,  48,  48,
     48, 204,  48,  48,  48,  48,  48,  48,  48,  48, 478,  48,  48,  48,  48,  48,
-    48,  48,  48,  48,  48,  48, 100, 140,  48, 204, 140, 140, 140, 140, 140, 140,
-    48,  48,  48,  48,  71,  48,  48,  48,  48,  48,  48, 140, 140, 140, 140, 140,
-   683, 140, 570, 570, 570, 570, 570, 570,  32,  32,  32,  32,  32,  32,  32,  32,
-    32,  32,  32,  32,  32,  32,  32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
-   391, 391, 391, 391, 391, 391, 391, 685,   0,   0,   0,   0,   0,   0,   0,   0,
-     1,   2,   2,   3,   1,   2,   2,   3,   0,   0,   0,   0,   0,   4,   0,   4,
-     2,   2,   5,   2,   2,   2,   5,   2,   2,   2,   2,   2,   2,   2,   2,   2,
-     2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   6,
-     0,   0,   0,   0,   7,   8,   0,   0,   9,   9,   9,   9,   9,   9,   9,   9,
-     9,   9,   9,   9,   9,   9,  10,  11,  12,  13,  14,  14,  15,  14,  14,  14,
-    14,  14,  14,  14,  16,  17,  14,  14,  18,  18,  18,  18,  18,  18,  18,  18,
-    18,  18,  18,  18,  18,  18,  18,  18,  19,  18,  18,  18,  18,  18,  18,  18,
-    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  20,  21,
-    21,  21,  22,  20,  21,  21,  21,  21,  21,  23,  24,  25,  25,  25,  25,  25,
-    25,  26,  25,  25,  25,  27,  28,  26,  29,  30,  31,  32,  31,  31,  31,  31,
-    33,  34,  35,  31,  31,  31,  36,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  29,  31,  31,  31,  31,  37,  38,  37,  37,  37,  37,  37,  37,
-    37,  39,  31,  31,  31,  31,  31,  31,  40,  40,  40,  40,  40,  40,  41,  26,
-    42,  42,  42,  42,  42,  42,  42,  43,  44,  44,  44,  44,  44,  45,  44,  46,
-    47,  47,  47,  48,  37,  49,  31,  31,  31,  50,  51,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  52,  31,  31,  31,  53,  53,  53,  53,  53,  53,  53,  53,
-    53,  53,  54,  53,  55,  53,  53,  53,  56,  57,  58,  59,  59,  60,  61,  62,
-    57,  63,  64,  65,  66,  59,  59,  67,  68,  69,  70,  71,  71,  72,  73,  74,
-    69,  75,  76,  77,  78,  71,  79,  26,  80,  81,  82,  83,  83,  84,  85,  86,
-    81,  87,  88,  26,  89,  83,  90,  91,  92,  93,  94,  95,  95,  96,  97,  98,
-    93,  99, 100, 101, 102,  95,  95,  26, 103, 104, 105, 106, 107, 104, 108, 109,
-   104, 105, 110,  26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116,
-   114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126,
-   123, 127, 128, 128, 129, 122, 130,  26, 131, 132, 133, 131, 131, 131, 131, 131,
-   132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141,
-   138, 142, 143, 137, 144, 137, 145,  26, 146, 147, 147, 147, 147, 147, 147, 148,
-   147, 147, 147, 149,  26,  26,  26,  26, 150, 151, 152, 152, 153, 152, 152, 154,
-   155, 156, 152, 157,  26,  26,  26,  26, 158, 158, 158, 158, 158, 158, 158, 158,
-   158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161,
-   158, 161, 162, 163,  26,  26,  26,  26, 164, 164, 164, 164, 164, 164, 164, 164,
-   164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165,
-   166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169,
-   169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170,
-   170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172,
-   171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170,
-   170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176,
-   176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178,
-   178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181,
-   181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188,  26,
-   189, 189, 190,  26, 191, 192, 193,  26, 194, 194, 194, 194, 194, 194, 194, 194,
-   194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, 198, 198, 198, 198,
-   198, 198, 198, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 201, 178, 178,
-   178, 178, 178, 178, 178, 178, 202,  26, 203, 203, 203, 204, 203, 205, 203, 205,
-   206, 203, 207, 207, 207, 208, 209,  26, 210, 210, 210, 210, 210, 211, 210, 210,
-   210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216,
-   216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220,   9,   9,
-     9, 221,  26,  26,  26,  26,  26,  26, 222, 222, 222, 222, 222, 222, 222, 222,
-   222, 223, 222, 222, 222, 222, 222, 224, 225, 225, 225, 225, 225, 225, 225, 225,
-   226, 226, 226, 226, 226, 226, 227, 228, 229, 229, 229, 229, 229, 229, 229, 230,
-   229, 231, 232, 232, 232, 232, 232, 232,  18, 233, 165, 165, 165, 165, 165, 234,
-   225,  26, 235,   9, 236, 237, 238, 239,   2,   2,   2,   2, 240, 241,   2,   2,
-     2,   2,   2, 242, 243, 244,   2, 245,   2,   2,   2,   2,   2,   2,   2, 246,
-     9,   9,   9,   9,   9,   9,   9,   9,  14,  14, 247, 247,  14,  14,  14,  14,
-   247, 247,  14, 248,  14,  14,  14, 247,  14,  14,  14,  14,  14,  14, 249,  14,
-   249,  14, 250, 251,  14,  14, 252, 253,   0, 254,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0, 255,   0, 256, 257,   0, 258,   2, 259,   0,   0,   0,   0,
-   260,  26,   9,   9,   9,   9, 261,  26,   0,   0,   0,   0, 262, 263,   4,   0,
-     0, 264,   0,   0,   2,   2,   2,   2,   2, 265,   0,   0,   0,   0,   0,   0,
+    48,  48,  48,  48,  48,  48, 100,  48,  48,  48,  48,  48,  48, 204, 140, 140,
+    48, 204, 140, 140, 140, 140, 140, 140,  48,  48,  48,  48,  71,  48,  48,  48,
+    48,  48,  48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 140,
+   391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686,
+     0,   0,   0,   0,   0,   0,   0,   0,   1,   2,   2,   3,   1,   2,   2,   3,
+     0,   0,   0,   0,   0,   4,   0,   4,   2,   2,   5,   2,   2,   2,   5,   2,
+     2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+     2,   2,   2,   2,   2,   2,   2,   6,   0,   0,   0,   0,   7,   8,   0,   0,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,  10,  11,
+    12,  13,  14,  14,  15,  14,  14,  14,  14,  14,  14,  14,  16,  17,  14,  14,
+    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,
+    19,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,
+    18,  18,  18,  18,  18,  18,  20,  21,  21,  21,  22,  20,  21,  21,  21,  21,
+    21,  23,  24,  25,  25,  25,  25,  25,  25,  26,  25,  25,  25,  27,  28,  26,
+    29,  30,  31,  32,  31,  31,  31,  31,  33,  34,  35,  31,  31,  31,  36,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  29,  31,  31,  31,  31,
+    37,  38,  37,  37,  37,  37,  37,  37,  37,  39,  31,  31,  31,  31,  31,  31,
+    40,  40,  40,  40,  40,  40,  41,  26,  42,  42,  42,  42,  42,  42,  42,  43,
+    44,  44,  44,  44,  44,  45,  44,  46,  47,  47,  47,  48,  37,  49,  31,  31,
+    31,  50,  51,  31,  31,  31,  31,  31,  31,  31,  31,  31,  52,  31,  31,  31,
+    53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  54,  53,  55,  53,  53,  53,
+    56,  57,  58,  59,  59,  60,  61,  62,  57,  63,  64,  65,  66,  59,  59,  67,
+    68,  69,  70,  71,  71,  72,  73,  74,  69,  75,  76,  77,  78,  71,  79,  26,
+    80,  81,  82,  83,  83,  84,  85,  86,  81,  87,  88,  26,  89,  83,  90,  91,
+    92,  93,  94,  95,  95,  96,  97,  98,  93,  99, 100, 101, 102,  95,  95,  26,
+   103, 104, 105, 106, 107, 104, 108, 109, 104, 105, 110,  26, 111, 108, 108, 112,
+   113, 114, 115, 113, 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113,
+   122, 123, 124, 122, 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130,  26,
+   131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131,
+   136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145,  26,
+   146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149,  26,  26,  26,  26,
+   150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157,  26,  26,  26,  26,
+   158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158,
+   158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163,  26,  26,  26,  26,
+   164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+   164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168,
+   169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169,
+   170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170,
+   170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170,
+   170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174,
+   170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177,
+   178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
+   179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183,
+   184, 184, 185, 186, 187, 187, 188,  26, 189, 189, 190,  26, 191, 192, 193,  26,
+   194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196,
+   197, 198, 198, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 200,
+   198, 198, 198, 198, 198, 201, 178, 178, 178, 178, 178, 178, 178, 178, 202,  26,
+   203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209,  26,
+   210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194,
+   214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218,
+   216, 219, 216, 219, 216, 220,   9,   9,   9, 221,  26,  26,  26,  26,  26,  26,
+   222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 224,
+   225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228,
+   229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232,
+    18, 233, 165, 165, 165, 165, 165, 234, 225,  26, 235,   9, 236, 237, 238, 239,
+     2,   2,   2,   2, 240, 241,   2,   2,   2,   2,   2, 242, 243, 244,   2, 245,
+     2,   2,   2,   2,   2,   2,   2, 246,   9,   9,   9,   9,   9,   9,   9,   9,
+    14,  14, 247, 247,  14,  14,  14,  14, 247, 247,  14, 248,  14,  14,  14, 247,
+    14,  14,  14,  14,  14,  14, 249,  14, 249,  14, 250, 251,  14,  14, 252, 253,
+     0, 254,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255,   0, 256, 257,
+     0, 258,   2, 259,   0,   0,   0,   0, 260,  26,   9,   9,   9,   9, 261,  26,
+     0,   0,   0,   0, 262, 263,   4,   0,   0, 264,   0,   0,   2,   2,   2,   2,
+     2, 265,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 258,  26,  26,  26,
-     0, 266,  26,  26,   0,   0,   0,   0, 267, 267, 267, 267, 267, 267, 267, 267,
-   267, 267, 267, 267, 267, 267, 267, 267,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 268,   0,   0,   0, 269,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 270, 270, 270, 270, 270, 270, 270, 270,
-   270, 270, 270, 270,   2,   2,   2,   2,  17,  17,  17,  17,  17,  17,  17,  17,
-    17,  17,  17,  17,  17,  17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273,
-   273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172,  26, 172, 172, 172, 172,
-   172, 172, 172, 172,  18,  18,  18,  18,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 276,  26,  26,  26,  26, 277, 277, 277, 278, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 277, 279,  26, 277, 277, 277, 277, 277, 277, 277, 277,
+     0,   0,   0,   0, 258,  26,  26,  26,   0, 266,  26,  26,   0,   0,   0,   0,
+   267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 268,   0,
+     0,   0, 269,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270,   2,   2,   2,   2,
+    17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17, 271, 272,
+   165, 165, 165, 165, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274,
+   170, 170, 172,  26, 172, 172, 172, 172, 172, 172, 172, 172,  18,  18,  18,  18,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 276,  26,  26,  26,  26,
+   277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279,  26,
    277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 280,  26,  26,  26,   0, 281, 282,   0,   0,   0, 283, 284,   0, 285,
-   286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291,
-   291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169,
-   169, 169, 169, 169, 169, 169, 169, 169, 169, 296,   0,   0, 294, 294, 294, 294,
-     0,   0,   0,   0, 281,  26, 291, 291, 169, 169, 169, 296,   0,   0,   0,   0,
-     0,   0,   0,   0, 169, 169, 169, 297,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291,
-   291, 291, 291,   0,   0,   0,   0,   0, 277, 277, 277, 277, 277, 277, 277, 277,
-     0,   0,   0,   0,   0,   0,   0,   0, 299, 299, 299, 299, 299, 299, 299, 299,
-   299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299,
-   301,  26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303,
-   303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304,  26,  26,
-    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18, 305, 305, 305, 305,
-   305, 305, 305, 305, 305, 305, 305,  26,   0,   0,   0,   0, 306,   2,   2,   2,
-     2,   2,   2,   2,   2,   2,   2,   2,   2, 307,   2,   2,   2,   2,   2,   2,
-     2, 308, 309, 310,  26,  26, 311,   2, 312, 312, 312, 312, 312, 313,   0, 314,
-   315, 315, 315, 315, 315, 315, 315,  26, 316, 316, 316, 316, 316, 316, 316, 316,
-   317, 318, 316, 319,  53,  53,  53,  53, 320, 320, 320, 320, 320, 321, 322, 322,
-   322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326,
-   326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331,  26,
-   330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334,
-   335,  26,  26, 336, 337, 337, 338,  26, 339, 339, 339,  26, 172, 172,   2,   2,
-     2,   2,   2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
-   337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345,  26, 169, 169,
-   296, 346, 169, 169, 169, 169, 169, 345,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 347,  26,  26,  26,  26, 348,  26, 349, 350,  25,  25, 351, 352,
-   353,  25,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-   354,  26, 355,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 356,
-    31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 357,  31,  31,  31,  31,  31,
-    31, 358,  26,  26,  26,  26,  31,  31,   9,   9,   0, 314,   9, 359,   0,   0,
-     0,   0, 360,   0, 258, 281, 361,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  31,  31,  31, 362, 363,   0,   0,   0,   1,   2,   2,   3,
-     1,   2,   2,   3, 364, 291, 290, 291, 291, 291, 291, 365, 169, 169, 169, 296,
-   366, 366, 366, 367, 258, 258,  26, 368, 369, 370, 369, 369, 371, 369, 369, 372,
-   369, 373, 369, 373,  26,  26,  26,  26, 369, 369, 369, 369, 369, 369, 369, 369,
-   369, 369, 369, 369, 369, 369, 369, 374, 375,   0,   0,   0,   0,   0, 376,   0,
-    14,  14,  14,  14,  14,  14,  14,  14,  14, 253,   0, 377, 378,  26,  26,  26,
-    26,  26,   0,   0,   0,   0,   0, 379, 380, 380, 380, 381, 382, 382, 382, 382,
-   382, 382, 383,  26, 384,   0,   0, 281, 385, 385, 385, 385, 386, 387, 388, 388,
-   388, 389, 390, 390, 390, 390, 390, 391, 392, 392, 392, 393, 394, 394, 394, 394,
-   395, 394, 396,  26,  26,  26,  26,  26, 397, 397, 397, 397, 397, 397, 397, 397,
-   397, 397, 398, 398, 398, 398, 398, 398, 399, 399, 399, 400, 399, 401, 402, 402,
-   402, 402, 403, 402, 402, 402, 402, 403, 404, 404, 404, 404, 404,  26, 405, 405,
-   405, 405, 405, 405, 406, 407, 408, 409, 408, 409, 410, 408, 411, 408, 411, 412,
-    26,  26,  26,  26,  26,  26,  26,  26, 413, 413, 413, 413, 413, 413, 413, 413,
-   413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 414,  26,
-   413, 413, 415,  26, 413,  26,  26,  26, 416,   2,   2,   2,   2,   2, 417, 308,
-    26,  26,  26,  26,  26,  26,  26,  26, 418, 419, 420, 420, 420, 420, 421, 422,
-   423, 423, 424, 423, 425, 425, 425, 425, 426, 426, 426, 427, 428, 426,  26,  26,
-    26,  26,  26,  26, 429, 429, 430, 431, 432, 432, 432, 433, 434, 434, 434, 435,
-    26,  26,  26,  26,  26,  26,  26,  26, 436, 436, 436, 436, 437, 437, 437, 438,
-   437, 437, 439, 437, 437, 437, 437, 437, 440, 441, 442, 443, 444, 444, 445, 446,
-   444, 447, 444, 447, 448, 448, 448, 448, 449, 449, 449, 449,  26,  26,  26,  26,
-   450, 450, 450, 450, 451, 452, 451,  26, 453, 453, 453, 453, 453, 453, 454, 455,
-   456, 456, 457, 456, 458, 458, 459, 458, 460, 460, 461, 462,  26, 463,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 464, 464, 464, 464, 464, 464, 464, 464,
-   464, 465,  26,  26,  26,  26,  26,  26, 466, 466, 466, 466, 466, 466, 467,  26,
-   466, 466, 466, 466, 466, 466, 467, 468, 469, 469, 469, 469, 469,  26, 469, 470,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  31,  31,  31,  50, 471, 471, 471, 471, 471, 472, 473,  26,
-    26,  26,  26,  26,  26,  26,  26, 474, 475, 475, 475, 475, 475,  26, 476, 476,
-   476, 476, 476, 477,  26,  26, 478, 478, 478, 479,  26,  26,  26,  26, 480, 480,
-   480, 481,  26,  26, 482, 482, 483,  26, 484, 484, 484, 484, 484, 484, 484, 484,
-   484, 485, 486, 484, 484, 484, 485, 487, 488, 488, 488, 488, 488, 488, 488, 488,
-   489, 490, 491, 491, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 495, 494,
-   494,  26, 496, 496, 496, 496, 497,  26, 498, 498, 498, 498, 498, 498, 498, 498,
-   498, 498, 498, 498, 499, 137, 500,  26, 501, 501, 502, 501, 501, 501, 501, 501,
-   503,  26,  26,  26,  26,  26,  26,  26, 504, 505, 506, 507, 506, 508, 509, 509,
-   509, 509, 509, 509, 509, 510, 509, 511, 512, 513, 514, 515, 515, 516, 517, 518,
-   513, 519, 520, 521, 522, 523, 523,  26, 524, 524, 524, 524, 524, 524, 524, 524,
-   524, 524, 524, 525, 526,  26,  26,  26, 527, 527, 527, 527, 527, 527, 527, 527,
-   527,  26, 527, 528,  26,  26,  26,  26, 529, 529, 529, 529, 529, 529, 530, 529,
-   529, 529, 529, 530,  26,  26,  26,  26, 531, 531, 531, 531, 531, 531, 531, 531,
-   532,  26, 531, 533, 198, 534,  26,  26, 535, 535, 535, 535, 535, 535, 535, 536,
-   535, 536,  26,  26,  26,  26,  26,  26, 537, 537, 537, 538, 537, 539, 537, 537,
-   540,  26,  26,  26,  26,  26,  26,  26, 541, 541, 541, 541, 541, 541, 541, 542,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 543, 543, 543, 543,
-   543, 543, 543, 543, 543, 543, 544, 545, 546, 547, 548, 549, 549, 549, 550, 551,
-   546,  26, 549, 552,  26,  26,  26,  26,  26,  26,  26,  26, 553, 554, 553, 553,
-   553, 553, 553, 554, 555,  26,  26,  26, 556, 556, 556, 556, 556, 556, 556, 556,
-   556,  26, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558,  26, 178, 178,
-   559, 559, 559, 559, 559, 559, 559, 560,  53, 561,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 562, 563, 562, 562, 562, 562, 564, 562,
-   565,  26, 562, 562, 562, 566, 567, 567, 567, 567, 568, 567, 567, 569, 570,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 571, 572, 573, 573, 573, 573, 571, 574,
-   573,  26, 573, 575, 576, 577, 578, 578, 578, 579, 580, 581, 578, 582,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26, 583, 583, 583, 584, 585, 585, 586, 585, 585, 585, 585, 587,
-   585, 585, 585, 588,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 589,  26,
-   108, 108, 108, 108, 108, 108, 590, 591, 592, 592, 592, 592, 592, 592, 592, 592,
-   592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 593,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 592, 592, 592, 592, 592, 592, 592, 592,
-   592, 592, 592, 592, 592, 594, 595,  26, 592, 592, 592, 592, 592, 592, 592, 592,
-   596,  26,  26,  26,  26,  26,  26,  26,  26,  26, 597, 597, 597, 597, 597, 597,
-   597, 597, 597, 597, 597, 597, 598,  26, 599, 599, 599, 599, 599, 599, 599, 599,
-   599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599,
-   599, 599, 600,  26,  26,  26,  26,  26, 601, 601, 601, 601, 601, 601, 601, 601,
-   601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601,
-   602,  26,  26,  26,  26,  26,  26,  26, 305, 305, 305, 305, 305, 305, 305, 305,
-   305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 603,
-   604, 604, 604, 605, 604, 606, 607, 607, 607, 607, 607, 607, 607, 607, 607, 608,
-   607, 609, 610, 610, 610, 611, 611,  26, 612, 612, 612, 612, 612, 612, 612, 612,
-   613,  26, 612, 614, 614, 612, 612, 615, 612, 612,  26,  26,  26,  26,  26,  26,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280,  26,  26,  26,   0,   0,
+   281,   0,   0,   0, 282, 283,   0, 284, 285, 286, 286, 286, 286, 286, 286, 286,
+   286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291,
+   292, 293, 293, 293, 293, 293, 294, 169, 169, 169, 169, 169, 169, 169, 169, 169,
+   169, 295,   0,   0, 293, 293, 293, 293,   0,   0,   0,   0, 296, 297, 290, 290,
+   169, 169, 169, 295,   0,   0,   0,   0,   0,   0,   0,   0, 169, 169, 169, 298,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 290, 290, 290, 290, 290, 299,
+   290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,   0,   0,   0,   0,   0,
+   277, 277, 277, 277, 277, 277, 277, 277,   0,   0,   0,   0,   0,   0,   0,   0,
+   300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
+   300, 301, 300, 300, 300, 300, 300, 300, 302,  26, 303, 303, 303, 303, 303, 303,
+   304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304,
+   304, 304, 304, 304, 304, 305,  26,  26,  18,  18,  18,  18,  18,  18,  18,  18,
+    18,  18,  18,  18, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,  26,
+     0,   0,   0,   0, 307,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+     2, 308,   2,   2,   2,   2,   2,   2,   2, 309, 310, 311,  26,  26, 312,   2,
+   313, 313, 313, 313, 313, 314,   0, 315, 316, 316, 316, 316, 316, 316, 316,  26,
+   317, 317, 317, 317, 317, 317, 317, 317, 318, 319, 317, 320,  53,  53,  53,  53,
+   321, 321, 321, 321, 321, 322, 323, 323, 323, 323, 324, 325, 169, 169, 169, 326,
+   327, 327, 327, 327, 327, 327, 327, 327, 327, 328, 327, 329, 164, 164, 164, 330,
+   331, 331, 331, 331, 331, 331, 332,  26, 331, 333, 331, 334, 164, 164, 164, 164,
+   335, 335, 335, 335, 335, 335, 335, 335, 336,  26,  26, 337, 338, 338, 339,  26,
+   340, 340, 340,  26, 172, 172,   2,   2,   2,   2,   2, 341, 342, 343, 176, 176,
+   176, 176, 176, 176, 176, 176, 176, 176, 338, 338, 338, 338, 338, 344, 338, 345,
+   169, 169, 169, 169, 346,  26, 169, 169, 295, 347, 169, 169, 169, 169, 169, 346,
     26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-   616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 618, 618, 618, 618, 618, 618, 618, 618,
-   618, 619, 618, 618, 618, 618, 618, 618, 618, 620, 618, 618,  26,  26,  26,  26,
-    26,  26,  26,  26, 621,  26, 347,  26, 622, 622, 622, 622, 622, 622, 622, 622,
-   622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622,
-   622, 622, 622, 622, 622, 622, 622,  26, 623, 623, 623, 623, 623, 623, 623, 623,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 348,  26,  26,  26,  26,
+   349,  26, 350, 351,  25,  25, 352, 353, 354,  25,  31,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31,  31, 355,  26, 356,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31, 357,  31,  31,  31,  31,  31,  31,  31,  31,
+    31,  31, 358,  31,  31,  31,  31,  31,  31, 359,  26,  26,  26,  26,  31,  31,
+     9,   9,   0, 315,   9, 360,   0,   0,   0,   0, 361,   0, 258, 296, 362,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 363,
+   364,   0,   0,   0,   1,   2,   2,   3,   1,   2,   2,   3, 365, 290, 289, 290,
+   290, 290, 290, 366, 169, 169, 169, 295, 367, 367, 367, 368, 258, 258,  26, 369,
+   370, 371, 370, 370, 372, 370, 370, 373, 370, 374, 370, 374,  26,  26,  26,  26,
+   370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 375,
+   376,   0,   0,   0,   0,   0, 377,   0,  14,  14,  14,  14,  14,  14,  14,  14,
+    14, 253,   0, 378, 379,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0, 380,
+   381, 381, 381, 382, 383, 383, 383, 383, 383, 383, 384,  26, 385,   0,   0, 296,
+   386, 386, 386, 386, 387, 388, 389, 389, 389, 390, 391, 391, 391, 391, 391, 392,
+   393, 393, 393, 394, 395, 395, 395, 395, 396, 395, 397,  26,  26,  26,  26,  26,
+   398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399,
+   400, 400, 400, 401, 400, 402, 403, 403, 403, 403, 404, 403, 403, 403, 403, 404,
+   405, 405, 405, 405, 405,  26, 406, 406, 406, 406, 406, 406, 407, 408, 409, 410,
+   409, 410, 411, 409, 412, 409, 412, 413,  26,  26,  26,  26,  26,  26,  26,  26,
+   414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414,
+   414, 414, 414, 414, 414, 414, 415,  26, 414, 414, 416,  26, 414,  26,  26,  26,
+   417,   2,   2,   2,   2,   2, 418, 309,  26,  26,  26,  26,  26,  26,  26,  26,
+   419, 420, 421, 421, 421, 421, 422, 423, 424, 424, 425, 424, 426, 426, 426, 426,
+   427, 427, 427, 428, 429, 427,  26,  26,  26,  26,  26,  26, 430, 430, 431, 432,
+   433, 433, 433, 434, 435, 435, 435, 436,  26,  26,  26,  26,  26,  26,  26,  26,
+   437, 437, 437, 437, 438, 438, 438, 439, 438, 438, 440, 438, 438, 438, 438, 438,
+   441, 442, 443, 444, 445, 445, 446, 447, 445, 448, 445, 448, 449, 449, 449, 449,
+   450, 450, 450, 450,  26,  26,  26,  26, 451, 451, 451, 451, 452, 453, 452,  26,
+   454, 454, 454, 454, 454, 454, 455, 456, 457, 457, 458, 457, 459, 459, 460, 459,
+   461, 461, 462, 463,  26, 464,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   465, 465, 465, 465, 465, 465, 465, 465, 465, 466,  26,  26,  26,  26,  26,  26,
+   467, 467, 467, 467, 467, 467, 468,  26, 467, 467, 467, 467, 467, 467, 468, 469,
+   470, 470, 470, 470, 470,  26, 470, 471,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  31,  31,  31,  50,
+   472, 472, 472, 472, 472, 473, 474,  26,  26,  26,  26,  26,  26,  26,  26, 475,
+   476, 476, 476, 476, 476,  26, 477, 477, 477, 477, 477, 478,  26,  26, 479, 479,
+   479, 480,  26,  26,  26,  26, 481, 481, 481, 482,  26,  26, 483, 483, 484,  26,
+   485, 485, 485, 485, 485, 485, 485, 485, 485, 486, 487, 485, 485, 485, 486, 488,
+   489, 489, 489, 489, 489, 489, 489, 489, 490, 491, 492, 492, 492, 493, 492, 494,
+   495, 495, 495, 495, 495, 495, 496, 495, 495,  26, 497, 497, 497, 497, 498,  26,
+   499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 500, 137, 501,  26,
+   502, 502, 503, 502, 502, 502, 502, 502, 504,  26,  26,  26,  26,  26,  26,  26,
+   505, 506, 507, 508, 507, 509, 510, 510, 510, 510, 510, 510, 510, 511, 510, 512,
+   513, 514, 515, 516, 516, 517, 518, 519, 514, 520, 521, 522, 523, 524, 524,  26,
+   525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 526, 527,  26,  26,  26,
+   528, 528, 528, 528, 528, 528, 528, 528, 528,  26, 528, 529,  26,  26,  26,  26,
+   530, 530, 530, 530, 530, 530, 531, 530, 530, 530, 530, 531,  26,  26,  26,  26,
+   532, 532, 532, 532, 532, 532, 532, 532, 533,  26, 532, 534, 198, 535,  26,  26,
+   536, 536, 536, 536, 536, 536, 536, 537, 536, 537,  26,  26,  26,  26,  26,  26,
+   538, 538, 538, 539, 538, 540, 538, 538, 541,  26,  26,  26,  26,  26,  26,  26,
+   542, 542, 542, 542, 542, 542, 542, 543,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 546,
+   547, 548, 549, 550, 550, 550, 551, 552, 547,  26, 550, 553,  26,  26,  26,  26,
+    26,  26,  26,  26, 554, 555, 554, 554, 554, 554, 554, 555, 556,  26,  26,  26,
+   557, 557, 557, 557, 557, 557, 557, 557, 557,  26, 558, 558, 558, 558, 558, 558,
+   558, 558, 558, 558, 559,  26, 178, 178, 560, 560, 560, 560, 560, 560, 560, 561,
+    53, 562,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   563, 564, 563, 563, 563, 563, 565, 563, 566,  26, 563, 563, 563, 567, 568, 568,
+   568, 568, 569, 568, 568, 570, 571,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   572, 573, 574, 574, 574, 574, 572, 575, 574,  26, 574, 576, 577, 578, 579, 579,
+   579, 580, 581, 582, 579, 583,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 584, 584, 584, 585,
+   586, 586, 587, 586, 586, 586, 586, 588, 586, 586, 586, 589,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26, 590,  26, 108, 108, 108, 108, 108, 108, 591, 592,
+   593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+   593, 593, 593, 594,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 595, 596,  26,
+   593, 593, 593, 593, 593, 593, 593, 593, 597,  26,  26,  26,  26,  26,  26,  26,
+    26,  26, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 599,  26,
+   600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
+   600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601,  26,  26,  26,  26,  26,
+   602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602,
+   602, 602, 602, 602, 602, 602, 602, 602, 603,  26,  26,  26,  26,  26,  26,  26,
+   306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+   306, 306, 306, 306, 306, 306, 306, 604, 605, 605, 605, 606, 605, 607, 608, 608,
+   608, 608, 608, 608, 608, 608, 608, 609, 608, 610, 611, 611, 611, 612, 612,  26,
+   613, 613, 613, 613, 613, 613, 613, 613, 614,  26, 613, 615, 615, 613, 613, 616,
+   613, 613,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26, 617, 617, 617, 617, 617, 617, 617, 617,
+   617, 617, 617, 618,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 619, 619, 619, 619, 619, 619,
+   619, 621, 619, 619,  26,  26,  26,  26,  26,  26,  26,  26, 622,  26, 348,  26,
    623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
-   623, 623, 624,  26,  26,  26,  26,  26, 622, 625,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26, 626, 627, 628, 287, 287, 287, 287, 287, 287, 287,
-   287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287,
-   287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 629,  26, 630,  26,
-    26,  26, 631,  26, 632,  26, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
-   633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
-   633, 633, 633, 633, 633, 633, 633, 634, 635, 635, 635, 635, 635, 635, 635, 635,
-   635, 635, 635, 635, 635, 636, 635, 637, 635, 638, 635, 639, 281,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   9,   9,   9,   9,   9, 640,   9,   9,
-   221,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-   281,  26,  26,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 276,  26,   0,   0,   0,   0, 258, 363,   0,   0,
-     0,   0,   0,   0, 641, 642,   0, 643, 644, 645,   0,   0,   0, 646,   0,   0,
-     0,   0,   0,   0,   0, 266,  26,  26,  14,  14,  14,  14,  14,  14,  14,  14,
-   247,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-     0,   0, 281,  26,   0,   0, 281,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 258,  26,   0,   0,   0, 260,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 255,   0,   0,   0,   0,   0,   0,   0,   0, 255, 647, 648,   0, 649,
-   650,   0,   0,   0,   0,   0,   0,   0, 269, 651, 255, 255,   0,   0,   0, 652,
-   653, 654, 655,   0,   0,   0,   0,   0,   0,   0,   0,   0, 276,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0, 268,   0,   0,   0,   0,   0,   0, 656, 656, 656, 656, 656, 656, 656, 656,
-   656, 656, 656, 656, 656, 656, 656, 656, 656, 657,  26, 658, 659, 656,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   2,   2,   2, 348, 660, 308,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 661, 270, 270, 662, 663, 664,  18,  18,
-    18,  18,  18,  18,  18, 665,  26,  26,  26, 666,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 667, 667, 667, 667, 667, 668, 667, 669,
-   667, 670,  26,  26,  26,  26,  26,  26,  26,  26, 671, 671, 671, 672,  26,  26,
-   673, 673, 673, 673, 673, 673, 673, 674,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26, 675, 675, 675, 675, 675, 676,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26, 172, 677, 170, 172, 678, 678, 678, 678, 678, 678, 678, 678,
-   678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678,
-   679, 678, 680,  26,  26,  26,  26,  26, 681, 681, 681, 681, 681, 681, 681, 681,
-   681, 682, 681, 683,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26, 363,   0,   0,   0,   0,   0,   0,   0, 377,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 363,   0,   0,   0,   0,   0,   0, 276,
-    26,  26,  26,  26,  26,  26,  26,  26, 684,  31,  31,  31, 685, 686, 687, 688,
-   689, 690, 685, 691, 685, 687, 687, 692,  31, 693,  31, 694, 695, 693,  31, 694,
-    26,  26,  26,  26,  26,  26,  51,  26,   0,   0,   0,   0,   0, 281,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 281,  26,   0, 258, 363,   0,
-   363,   0, 363,   0,   0,   0, 276,  26,   0,   0,   0,   0,   0, 276,  26,  26,
-    26,  26,  26,  26, 696,   0,   0,   0, 697,  26,   0,   0,   0,   0,   0, 281,
-     0, 260, 314,  26, 276,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 698,   0, 377,   0, 377,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 258, 699,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 314,   0, 281, 260,  26,   0, 281,   0,   0,   0,   0,   0,   0,
-     0,  26,   0, 314,   0,   0,   0,   0,   0,  26,   0,   0,   0, 276, 314,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 281,  26,   0, 276,   0, 377,   0, 260,   0,   0,   0,   0,   0, 269,
-   276, 696,   0, 281,   0, 260,   0, 260,   0,   0, 360,   0,   0,   0,   0,   0,
-     0, 266,  26,  26,  26,  26,   0, 314, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 347,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347,  26, 277, 277,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277, 700,  26,  26,  26, 277, 277, 277, 280,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 701, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 702,  26,  26,  26,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   9,   9,   9,   9,   9,   9,   9,   9,
+   623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,  26,
+   624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624,
+   624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625,  26,  26,  26,  26,  26,
+   623, 626,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 627, 628,
+   629, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286,
+   286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286,
+   286, 286, 286, 286, 630,  26, 631,  26,  26,  26, 632,  26, 633,  26, 634, 634,
+   634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634,
+   634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 635,
+   636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 636, 638,
+   636, 639, 636, 640, 296,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     9,   9,   9,   9,   9, 641,   9,   9, 221,  26,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0, 296,  26,  26,  26,  26,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 276,  26,
+     0,   0,   0,   0, 258, 364,   0,   0,   0,   0,   0,   0, 642, 643,   0, 644,
+   645, 646,   0,   0,   0, 647,   0,   0,   0,   0,   0,   0,   0, 266,  26,  26,
+    14,  14,  14,  14,  14,  14,  14,  14, 247,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,   0,   0, 296,  26,   0,   0, 296,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 258,  26,   0,   0,   0, 260,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255,   0,   0,   0,   0,   0,
+     0,   0,   0, 255, 648, 649,   0, 650, 651,   0,   0,   0,   0,   0,   0,   0,
+   269, 652, 255, 255,   0,   0,   0, 653, 654, 655, 656,   0,   0,   0,   0,   0,
+     0,   0,   0,   0, 276,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0, 268,   0,   0,   0,   0,   0,   0,
+   657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
+   657, 658,  26, 659, 660, 657,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     2,   2,   2, 349, 661, 309,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   662, 270, 270, 663, 664, 665,  18,  18,  18,  18,  18,  18,  18, 666,  26,  26,
+    26, 667,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   668, 668, 668, 668, 668, 669, 668, 670, 668, 671,  26,  26,  26,  26,  26,  26,
+    26,  26, 672, 672, 672, 673,  26,  26, 674, 674, 674, 674, 674, 674, 674, 675,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 676, 676, 676, 676, 676, 677,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 172, 678, 170, 172,
+   679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679,
+   679, 679, 679, 679, 679, 679, 679, 679, 680, 679, 681,  26,  26,  26,  26,  26,
+   682, 682, 682, 682, 682, 682, 682, 682, 682, 683, 682, 684,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 364,   0,
+     0,   0,   0,   0,   0,   0, 378,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   364,   0,   0,   0,   0,   0,   0, 276,  26,  26,  26,  26,  26,  26,  26,  26,
+   685,  31,  31,  31, 686, 687, 688, 689, 690, 691, 686, 692, 686, 688, 688, 693,
+    31, 694,  31, 695, 696, 694,  31, 695,  26,  26,  26,  26,  26,  26,  51,  26,
+     0,   0,   0,   0,   0, 296,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0, 296,  26,   0, 258, 364,   0, 364,   0, 364,   0,   0,   0, 276,  26,
+     0,   0,   0,   0,   0, 276,  26,  26,  26,  26,  26,  26, 697,   0,   0,   0,
+   698,  26,   0,   0,   0,   0,   0, 296,   0, 260, 315,  26, 276,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 699,   0, 378,   0, 378,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 258, 700,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 315,   0, 296, 260,  26,
+     0, 296,   0,   0,   0,   0,   0,   0,   0,  26,   0, 315,   0,   0,   0,   0,
+     0,  26,   0,   0,   0, 276, 315,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 296,  26,   0, 276,   0, 378,
+     0, 260,   0,   0,   0,   0,   0, 269, 276, 697,   0, 296,   0, 260,   0, 260,
+     0,   0, 361,   0,   0,   0,   0,   0,   0, 266,  26,  26,  26,  26,   0, 315,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,  26,  26,  26,  26,
+   277, 277, 277, 277, 277, 277, 277, 348, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 277, 348,  26, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 701,  26, 277, 277,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280,  26,  26,  26,  26,
+   277, 277, 277, 280,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 702, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 277, 277, 277,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   703,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,
-     9,   9,   9,   9,   9,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 939, 940, 941, 942, 946, 948,   0, 962,
-   969, 970, 971, 976,1001,1002,1003,1008,   0,1033,1040,1041,1042,1043,1047,   0,
-     0,1080,1081,1082,1086,1110,   0,   0,1124,1125,1126,1127,1131,1133,   0,1147,
-  1154,1155,1156,1161,1187,1188,1189,1193,   0,1219,1226,1227,1228,1229,1233,   0,
-     0,1267,1268,1269,1273,1298,   0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
-   959,1144, 960,1145, 961,1146, 964,1149,   0,   0, 973,1158, 974,1159, 975,1160,
-   983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179,   0,   0,
-  1004,1190,1005,1191,1006,1192,1014,1199,1007,   0,   0,   0,1016,1201,1020,1206,
-     0,1022,1208,1025,1211,1023,1209,   0,   0,   0,   0,1032,1218,1037,1223,1035,
-  1221,   0,   0,   0,1044,1230,1045,1231,1049,1235,   0,   0,1058,1244,1064,1250,
-  1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261,   0,   0,
-  1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
-  1115,1118,1307,1120,1309,1121,1310,   0,1053,1239,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,1093,1280,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
-  1367,1342,1369,1339,1366,   0,1320,1347,1418,1419,1323,1350,   0,   0, 992,1177,
-  1018,1204,1055,1241,1416,1417,1415,1424,1202,   0,   0,   0, 987,1172,   0,   0,
-  1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
-  1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
-  1071,1257,1076,1263,   0,   0, 997,1182,   0,   0,   0,   0,   0,   0, 945,1130,
-   982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   8,   9,   0,  10,1425,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,1314,1427,   5,
-  1434,1438,1443,   0,1450,   0,1455,1461,1514,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1446,1458,1468,1476,1480,1486,1517,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1489,1503,1494,1500,1508,   0,   0,   0,   0,1520,1521,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1526,1528,   0,1525,   0,   0,   0,1522,
-     0,   0,   0,   0,1536,1532,1539,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1534,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1556,   0,   0,   0,   0,   0,   0,1548,1550,   0,1547,   0,   0,   0,1567,
-     0,   0,   0,   0,1558,1554,1561,   0,   0,   0,   0,   0,   0,   0,1568,1569,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1529,1551,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1523,1545,1524,1546,   0,   0,1527,1549,
-     0,   0,1570,1571,1530,1552,1531,1553,   0,   0,1533,1555,1535,1557,1537,1559,
-     0,   0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564,   0,   0,
-  1543,1565,   0,   0,   0,   0,   0,   0,   0,   0,1606,1607,1609,1608,1610,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1613,   0,1611,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1612,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1620,   0,   0,   0,   0,   0,   0,   0,1623,   0,   0,1624,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1614,1615,1616,1617,1618,1619,1621,1622,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1628,1629,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1625,1626,   0,1627,   0,   0,   0,1634,   0,   0,1635,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1630,1631,1632,   0,   0,1633,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1639,   0,   0,1638,1640,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1636,1637,   0,   0,   0,   0,   0,   0,1641,   0,   0,   0,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1642,1644,1643,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1645,   0,   0,   0,   0,   0,   0,   0,1646,   0,   0,   0,   0,   0,   0,1648,
-  1649,   0,1647,1650,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1651,1653,1652,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1654,   0,1655,1657,1656,   0,   0,   0,   0,1659,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1660,   0,   0,   0,   0,1661,   0,   0,   0,   0,1662,
-     0,   0,   0,   0,1663,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1658,   0,   0,   0,   0,   0,   0,   0,   0,   0,1664,   0,1665,1673,   0,
-  1674,   0,   0,   0,   0,   0,   0,   0,   0,1666,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1668,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1669,   0,   0,   0,   0,1670,   0,   0,   0,   0,1671,
-     0,   0,   0,   0,1672,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1667,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1675,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1676,   0,
-  1677,   0,1678,   0,1679,   0,1680,   0,   0,   0,1681,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1682,   0,1683,   0,   0,1684,1685,   0,1686,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 953,1138, 955,1140, 956,1141, 957,1142,
-  1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
-   984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
-   999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
-  1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
-  1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
-  1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
-  1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
-  1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
-  1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
-  1293,1305,   0,1394,   0,   0,   0,   0, 952,1137, 947,1132,1317,1344,1316,1343,
-  1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
-   981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
-  1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
-  1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
-  1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
-  1112,1300,   0,   0,   0,   0,   0,   0,1471,1472,1701,1705,1702,1706,1703,1707,
-  1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732,   0,   0,
-  1435,1436,1733,1735,1734,1736,   0,   0,1481,1482,1737,1741,1738,1742,1739,1743,
-  1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
-  1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780,   0,   0,
-  1451,1452,1781,1783,1782,1784,   0,   0,1504,1505,1785,1788,1786,1789,1787,1790,
-     0,1459,   0,1791,   0,1792,   0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
-  1462,1463,1808,1812,1809,1813,1810,1814,1467,  21,1475,  22,1479,  23,1485,  24,
-  1493,  27,1499,  28,1507,  29,   0,   0,1704,1708,1709,1710,1711,1712,1713,1714,
-  1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
-  1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
-  1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465,   0,1473,1825,
-  1429,1428,1426,  12,1432,   0,  26,   0,   0,1315,1823,1484,1466,   0,1483,1829,
-  1433,  13,1437,  14,1441,1826,1827,1828,1488,1487,1513,  19,   0,   0,1492,1515,
-  1445,1444,1442,  15,   0,1831,1832,1833,1502,1501,1516,  25,1497,1498,1506,1518,
-  1457,1456,1454,  17,1453,1313,  11,   3,   0,   0,1824,1512,1519,   0,1511,1830,
-  1449,  16,1460,  18,1464,   4,   0,   0,  30,  31,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  20,   0,
-     0,   0,   2,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1834,1835,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1836,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1837,1839,1838,   0,   0,   0,   0,1840,   0,   0,   0,
-     0,1841,   0,   0,1842,   0,   0,   0,   0,   0,   0,   0,1843,   0,1844,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1845,   0,   0,1846,   0,   0,1847,
-     0,1848,   0,   0,   0,   0,   0,   0, 937,   0,1850,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1849, 936, 938,1851,1852,   0,   0,1853,1854,   0,   0,
-  1855,1856,   0,   0,   0,   0,   0,   0,1857,1858,   0,   0,1861,1862,   0,   0,
-  1863,1864,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1867,1868,1869,1870,1859,1860,1865,1866,   0,   0,   0,   0,
-     0,   0,1871,1872,1873,1874,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,  32,  33,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1875,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1877,   0,1878,   0,1879,   0,1880,   0,1881,   0,1882,   0,
-  1883,   0,1884,   0,1885,   0,1886,   0,1887,   0,1888,   0,   0,1889,   0,1890,
-     0,1891,   0,   0,   0,   0,   0,   0,1892,1893,   0,1894,1895,   0,1896,1897,
-     0,1898,1899,   0,1900,1901,   0,   0,   0,   0,   0,   0,1876,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1902,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1904,   0,1905,   0,1906,   0,1907,   0,1908,   0,1909,   0,
-  1910,   0,1911,   0,1912,   0,1913,   0,1914,   0,1915,   0,   0,1916,   0,1917,
-     0,1918,   0,   0,   0,   0,   0,   0,1919,1920,   0,1921,1922,   0,1923,1924,
-     0,1925,1926,   0,1927,1928,   0,   0,   0,   0,   0,   0,1903,   0,   0,1929,
-  1930,1931,1932,   0,   0,   0,1933,   0, 710, 385, 724, 715, 455, 103, 186, 825,
-   825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
-   649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
-   293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
-   781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
-   714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
-   648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
-   430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
-   135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
-   812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
-   726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
-   113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
-   774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
-   395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
-   305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
-   687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
-   568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
-   680, 767, 694, 295, 128, 210,   0,   0, 227,   0, 379,   0,   0, 150, 493, 525,
-   544, 551, 552, 556, 783, 576, 604,   0, 661,   0, 703,   0,   0, 735, 743,   0,
-     0,   0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
-   215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
-   477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
-   593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
-   777, 786, 790, 315, 869, 623,   0,   0, 102, 145, 134, 115, 129, 138, 165, 171,
-   207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
-   321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
-   456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
-   528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
-   695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
-   783, 784, 786, 787, 790, 802, 825, 848, 847, 857,  55,  65,  66, 883, 892, 916,
-   822, 824,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1586,   0,1605,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584,   0,
-  1585,1587,1588,1589,1591,   0,1592,   0,1593,1594,   0,1595,1596,   0,1598,1599,
-  1600,1601,1604,1582,1578,1590,1597,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1936,   0,1937,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1938,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1939,1940,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1941,1942,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1944,1943,   0,1945,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1946,1947,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1948,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1949,1950,1951,1952,1953,1954,1955,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1956,1957,1958,1960,1959,1961,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 106, 104, 107, 826, 114, 118, 119, 121,
-   123, 124, 127, 125,  34, 830, 130, 131, 132, 137, 827,  35, 133, 139, 829, 142,
-   143, 112, 144, 145, 924, 151, 152,  37, 157, 158, 159, 160,  38, 165, 166, 169,
-   171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
-   834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
-   208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
-   230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251,  39,
-    40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264,  41, 266,
-   270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282,  42, 283, 284, 285, 286,
-    43, 843,  44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300,  45, 852,
-   894, 302, 304,  46, 306, 309, 310, 312, 316,  48,  47, 317, 846, 318, 323, 324,
-   325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
-   849, 350, 348, 352, 354, 359, 850, 361, 358, 356,  49, 363, 365, 367, 364,  50,
-   369, 371, 851, 376, 386, 378,  53, 381,  52,  51, 140, 141, 387, 382, 614,  78,
-   388, 389, 390, 394, 392, 856,  54, 399, 396, 402, 404, 858, 405, 401, 407,  55,
-   408, 409, 410, 413, 859, 415,  56, 417, 860, 418,  57, 419, 422, 424, 425, 861,
-   840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
-   449, 450,  58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464,  59, 467,
-   470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
-   495, 497,  60, 498,  61,  61, 504, 505, 507, 508, 511,  62, 513, 874, 515, 875,
-   518, 844, 520, 876, 877, 878,  63,  64, 528, 880, 879, 881, 882, 530, 531, 531,
-   533,  66, 534,  67,  68, 884, 536, 538, 541,  69, 885, 549, 886, 887, 556, 559,
-    70, 561, 562, 563, 888, 889, 889, 567,  71, 890, 570, 571,  72, 891, 577,  73,
-   581, 579, 582, 893, 587,  74, 590, 592, 596,  75, 895, 896,  76, 897, 600, 898,
-   602, 605, 607, 899, 900, 609, 901, 611, 853,  77, 615, 616,  79, 617, 252, 902,
-   903, 854, 855, 621, 622, 731,  80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
-   632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906,  81,
-   653, 654, 656, 911, 657, 908,  82,  83, 909, 910,  84, 664, 665, 666, 667, 669,
-   668, 671, 670, 674, 672, 673, 675,  85, 677, 678,  86, 681, 682, 912, 685, 686,
-    87, 689,  36, 913, 914,  88,  89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
-   917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
-   756, 757, 755, 760, 761, 921, 762,  90, 764, 922,  91, 775, 279, 780, 923, 925,
-    92,  93, 785, 926,  94, 927, 787, 787, 789, 928, 792,  95, 796, 797, 798, 800,
-    96, 929, 802, 804, 806,  97,  98, 807, 930,  99, 931, 932, 933, 814, 100, 816,
-   817, 818, 819, 820, 821, 935,   0,   0,
+   939, 940, 941, 942, 946, 948,   0, 962, 969, 970, 971, 976,1001,1002,1003,1008,
+     0,1033,1040,1041,1042,1043,1047,   0,   0,1080,1081,1082,1086,1110,   0,   0,
+  1124,1125,1126,1127,1131,1133,   0,1147,1154,1155,1156,1161,1187,1188,1189,1193,
+     0,1219,1226,1227,1228,1229,1233,   0,   0,1267,1268,1269,1273,1298,   0,1303,
+   943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149,
+     0,   0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175,
+   991,1176, 993,1178, 994,1179,   0,   0,1004,1190,1005,1191,1006,1192,1014,1199,
+  1007,   0,   0,   0,1016,1201,1020,1206,   0,1022,1208,1025,1211,1023,1209,   0,
+     0,   0,   0,1032,1218,1037,1223,1035,1221,   0,   0,   0,1044,1230,1045,1231,
+  1049,1235,   0,   0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,
+  1069,1255,1077,1264,1074,1261,   0,   0,1083,1270,1084,1271,1085,1272,1088,1275,
+  1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310,   0,
+  1053,1239,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1093,
+  1280,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 949,1134,1010,
+  1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366,   0,1320,1347,
+  1418,1419,1323,1350,   0,   0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,
+  1202,   0,   0,   0, 987,1172,   0,   0,1031,1217,1321,1348,1322,1349,1338,1365,
+   950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,
+  1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263,   0,   0, 997,1182,
+     0,   0,   0,   0,   0,   0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,
+  1422,1423,1113,1301,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     8,   9,   0,  10,1425,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+     0,   0,   0,   0,   0,1314,1427,   5,1434,1438,1443,   0,1450,   0,1455,1461,
+  1514,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1446,1458,1468,1476,1480,1486,
+  1517,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1489,1503,1494,1500,1508,   0,
+     0,   0,   0,1520,1521,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1526,1528,   0,1525,   0,   0,   0,1522,   0,   0,   0,   0,1536,1532,1539,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1534,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1556,   0,   0,   0,   0,   0,   0,
+  1548,1550,   0,1547,   0,   0,   0,1567,   0,   0,   0,   0,1558,1554,1561,   0,
+     0,   0,   0,   0,   0,   0,1568,1569,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1529,1551,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1523,1545,1524,1546,   0,   0,1527,1549,   0,   0,1570,1571,1530,1552,1531,1553,
+     0,   0,1533,1555,1535,1557,1537,1559,   0,   0,1572,1573,1544,1566,1538,1560,
+  1540,1562,1541,1563,1542,1564,   0,   0,1543,1565,   0,   0,   0,   0,   0,   0,
+     0,   0,1606,1607,1609,1608,1610,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1613,   0,1611,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1612,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1620,   0,   0,   0,   0,   0,   0,
+     0,1623,   0,   0,1624,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1614,1615,1616,1617,1618,1619,1621,1622,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1628,1629,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1625,1626,   0,1627,
+     0,   0,   0,1634,   0,   0,1635,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1630,1631,1632,   0,   0,1633,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1639,   0,   0,1638,1640,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1636,1637,   0,   0,
+     0,   0,   0,   0,1641,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1642,1644,1643,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1645,   0,   0,   0,   0,   0,   0,   0,
+  1646,   0,   0,   0,   0,   0,   0,1648,1649,   0,1647,1650,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1651,1653,1652,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1654,   0,1655,1657,1656,   0,
+     0,   0,   0,1659,   0,   0,   0,   0,   0,   0,   0,   0,   0,1660,   0,   0,
+     0,   0,1661,   0,   0,   0,   0,1662,   0,   0,   0,   0,1663,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1658,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1664,   0,1665,1673,   0,1674,   0,   0,   0,   0,   0,   0,   0,
+     0,1666,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1668,   0,   0,   0,   0,   0,   0,   0,   0,   0,1669,   0,   0,
+     0,   0,1670,   0,   0,   0,   0,1671,   0,   0,   0,   0,1672,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1667,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1675,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1676,   0,1677,   0,1678,   0,1679,   0,1680,   0,
+     0,   0,1681,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1682,   0,1683,   0,   0,
+  1684,1685,   0,1686,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153,
+   966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171,
+   989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,
+  1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,
+  1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,
+  1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,
+  1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,
+  1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,
+  1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,
+  1119,1308,1122,1311,1123,1312,1186,1260,1293,1305,   0,1394,   0,   0,   0,   0,
+   952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,
+  1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,
+  1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,
+  1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,
+  1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,
+  1409,1414,1109,1297,1117,1306,1116,1304,1112,1300,   0,   0,   0,   0,   0,   0,
+  1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,
+  1477,1478,1729,1731,1730,1732,   0,   0,1435,1436,1733,1735,1734,1736,   0,   0,
+  1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,
+  1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,
+  1495,1496,1777,1779,1778,1780,   0,   0,1451,1452,1781,1783,1782,1784,   0,   0,
+  1504,1505,1785,1788,1786,1789,1787,1790,   0,1459,   0,1791,   0,1792,   0,1793,
+  1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,
+  1467,  21,1475,  22,1479,  23,1485,  24,1493,  27,1499,  28,1507,  29,   0,   0,
+  1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,
+  1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,
+  1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,
+  1470,1469,1822,1474,1465,   0,1473,1825,1429,1428,1426,  12,1432,   0,  26,   0,
+     0,1315,1823,1484,1466,   0,1483,1829,1433,  13,1437,  14,1441,1826,1827,1828,
+  1488,1487,1513,  19,   0,   0,1492,1515,1445,1444,1442,  15,   0,1831,1832,1833,
+  1502,1501,1516,  25,1497,1498,1506,1518,1457,1456,1454,  17,1453,1313,  11,   3,
+     0,   0,1824,1512,1519,   0,1511,1830,1449,  16,1460,  18,1464,   4,   0,   0,
+    30,  31,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,  20,   0,   0,   0,   2,   6,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1834,1835,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1836,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1837,1839,1838,
+     0,   0,   0,   0,1840,   0,   0,   0,   0,1841,   0,   0,1842,   0,   0,   0,
+     0,   0,   0,   0,1843,   0,1844,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1845,   0,   0,1846,   0,   0,1847,   0,1848,   0,   0,   0,   0,   0,   0,
+   937,   0,1850,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1849, 936, 938,
+  1851,1852,   0,   0,1853,1854,   0,   0,1855,1856,   0,   0,   0,   0,   0,   0,
+  1857,1858,   0,   0,1861,1862,   0,   0,1863,1864,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1867,1868,1869,1870,
+  1859,1860,1865,1866,   0,   0,   0,   0,   0,   0,1871,1872,1873,1874,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,  32,  33,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1875,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1877,   0,1878,   0,
+  1879,   0,1880,   0,1881,   0,1882,   0,1883,   0,1884,   0,1885,   0,1886,   0,
+  1887,   0,1888,   0,   0,1889,   0,1890,   0,1891,   0,   0,   0,   0,   0,   0,
+  1892,1893,   0,1894,1895,   0,1896,1897,   0,1898,1899,   0,1900,1901,   0,   0,
+     0,   0,   0,   0,1876,   0,   0,   0,   0,   0,   0,   0,   0,   0,1902,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1904,   0,1905,   0,
+  1906,   0,1907,   0,1908,   0,1909,   0,1910,   0,1911,   0,1912,   0,1913,   0,
+  1914,   0,1915,   0,   0,1916,   0,1917,   0,1918,   0,   0,   0,   0,   0,   0,
+  1919,1920,   0,1921,1922,   0,1923,1924,   0,1925,1926,   0,1927,1928,   0,   0,
+     0,   0,   0,   0,1903,   0,   0,1929,1930,1931,1932,   0,   0,   0,1933,   0,
+   710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601,
+   663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662,
+   810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168,
+   368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758,
+   811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585,
+   594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259,
+   313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697,
+   424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170,
+   193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330,
+   337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473,
+   683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603,
+   608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411,
+   479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583,
+   791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269,
+   377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510,
+   659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156,
+   153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210,   0,   0,
+   227,   0, 379,   0,   0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604,   0,
+   661,   0, 703,   0,   0, 735, 743,   0,   0,   0, 793, 794, 795, 808, 741, 773,
+   118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329,
+   335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548,
+   549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651,
+   690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623,   0,   0,
+   102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243,
+   250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362,
+   370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490,
+   493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586,
+   591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706,
+   709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848,
+   847, 857,  55,  65,  66, 883, 892, 916, 822, 824,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1586,   0,1605,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1602,1603,1934,1935,1574,1575,
+  1576,1577,1579,1580,1581,1583,1584,   0,1585,1587,1588,1589,1591,   0,1592,   0,
+  1593,1594,   0,1595,1596,   0,1598,1599,1600,1601,1604,1582,1578,1590,1597,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1936,   0,1937,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1938,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1939,1940,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1941,1942,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1944,1943,   0,1945,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1946,1947,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1948,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1949,1950,
+  1951,1952,1953,1954,1955,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1956,1957,1958,1960,1959,
+  1961,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125,  34, 830, 130, 131,
+   132, 137, 827,  35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152,  37,
+   157, 158, 159, 160,  38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179,
+   181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195,
+   197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216,
+   153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244,
+   836, 837, 247, 248, 249, 246, 251,  39,  40, 253, 255, 255, 838, 257, 258, 259,
+   261, 839, 262, 263, 301, 264,  41, 266, 270, 272, 271, 841, 274, 842, 277, 276,
+   278, 281, 282,  42, 283, 284, 285, 286,  43, 843,  44, 289, 290, 291, 293, 934,
+   298, 845, 845, 621, 300, 300,  45, 852, 894, 302, 304,  46, 306, 309, 310, 312,
+   316,  48,  47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334,
+   335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361,
+   358, 356,  49, 363, 365, 367, 364,  50, 369, 371, 851, 376, 386, 378,  53, 381,
+    52,  51, 140, 141, 387, 382, 614,  78, 388, 389, 390, 394, 392, 856,  54, 399,
+   396, 402, 404, 858, 405, 401, 407,  55, 408, 409, 410, 413, 859, 415,  56, 417,
+   860, 418,  57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433,
+   437, 441, 438, 439, 442, 443, 864, 436, 449, 450,  58, 454, 453, 865, 447, 460,
+   866, 867, 461, 466, 465, 464,  59, 467, 470, 469, 472, 828, 475, 868, 478, 870,
+   483, 485, 486, 871, 488, 489, 872, 873, 495, 497,  60, 498,  61,  61, 504, 505,
+   507, 508, 511,  62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878,  63,  64,
+   528, 880, 879, 881, 882, 530, 531, 531, 533,  66, 534,  67,  68, 884, 536, 538,
+   541,  69, 885, 549, 886, 887, 556, 559,  70, 561, 562, 563, 888, 889, 889, 567,
+    71, 890, 570, 571,  72, 891, 577,  73, 581, 579, 582, 893, 587,  74, 590, 592,
+   596,  75, 895, 896,  76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611,
+   853,  77, 615, 616,  79, 617, 252, 902, 903, 854, 855, 621, 622, 731,  80, 627,
+   626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651,
+   638, 643, 644, 645, 905, 907, 906,  81, 653, 654, 656, 911, 657, 908,  82,  83,
+   909, 910,  84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675,  85,
+   677, 678,  86, 681, 682, 912, 685, 686,  87, 689,  36, 913, 914,  88,  89, 696,
+   702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728,
+   918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762,  90,
+   764, 922,  91, 775, 279, 780, 923, 925,  92,  93, 785, 926,  94, 927, 787, 787,
+   789, 928, 792,  95, 796, 797, 798, 800,  96, 929, 802, 804, 806,  97,  98, 807,
+   930,  99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935,   0,   0,
 };
 static const int16_t
 _hb_ucd_i16[196] =
@@ -2797,12 +2799,12 @@
 static inline uint_fast8_t
 _hb_ucd_gc (unsigned u)
 {
-  return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+  return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
 }
 static inline uint_fast8_t
 _hb_ucd_ccc (unsigned u)
 {
-  return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+  return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
 }
 static inline unsigned
 _hb_ucd_b4 (const uint8_t* a, unsigned i)
@@ -2812,24 +2814,24 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9548+(((_hb_ucd_u8[9428+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
+  return u<918000u?_hb_ucd_u8[11070+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10334+(((_hb_ucd_u8[9884+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[6032+(((_hb_ucd_u8[17084+(((_hb_ucd_u8[16702+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 
 #elif !defined(HB_NO_UCD_UNASSIGNED)
 
 static const uint8_t
-_hb_ucd_u8[14744] =
+_hb_ucd_u8[14752] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7, 11, 12, 13, 13, 13, 14,
@@ -2906,13 +2908,13 @@
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
   244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
-  250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
-  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
+   34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122,
+   34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122,
+   34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122,
+  251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122,
   107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
+  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255,
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
     7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
@@ -3075,11 +3077,11 @@
   121,  4,  4,  4,  4,  2,  2, 88,  2,  2,  2,  2,  2,120,  2,  2,
   108,151,  2,  2,  2,  2,  2,  2, 67,  2,152,148,148,148,153, 44,
    67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
-    1,  2,154,155,  4,  4,  4,  4,  4, 67,  4,  4,  4,  4,156,157,
-  158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
-   36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
-   44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
+   67, 67, 67, 44, 44, 44, 44, 44,  1,  2,154,155,  4,  4,  4,  4,
+    4, 67,  4,  4,  4,  4,156,157,158,105,105,105,105, 43, 43, 86,
+  159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69,
+   36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36,
+   67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55,
    67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
    67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
    36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164,  2,
@@ -3247,218 +3249,218 @@
    44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
    62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
    36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
-    8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
-   27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
-   44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
-   67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
-   67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
-  171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171,  0,
-    0,  0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
-   25, 25, 25, 21, 21,  9,  9,  9,  9, 22, 21, 18, 24, 16, 24,  5,
-    5,  5,  5, 22, 25, 18, 25,  0, 23, 23, 26, 21, 24, 26,  7, 20,
-   25,  1, 26, 24, 26, 25, 15, 15, 24, 15,  7, 19, 15, 21,  9, 25,
-    9,  5,  5, 25,  5,  9,  5,  7,  7,  7,  9,  8,  8,  5,  7,  5,
-    6,  6, 24, 24,  6, 24, 12, 12,  2,  2,  6,  5,  9, 21,  9,  2,
-    2,  9, 25,  9, 26, 12, 11, 11,  2,  6,  5, 21, 17,  2,  2, 26,
-   26, 23,  2, 12, 17, 12, 21, 12, 12, 21,  7,  2,  2,  7,  7, 21,
-   21,  2,  1,  1, 21, 23, 26, 26,  1, 21,  6,  7,  7, 12, 12,  7,
-   21,  7, 12,  1, 12,  6,  6, 12, 12, 26,  7, 26, 26,  7,  2,  1,
-   12,  2,  6,  2, 24,  7,  7,  6,  1, 12, 12, 10, 10, 10, 10, 12,
-   21,  6,  2, 10, 10,  2, 15, 26, 26,  2,  2, 21,  7, 10, 15,  7,
-    2, 23, 21, 26, 10,  7, 21, 15, 15,  2, 17,  7, 29,  7,  7, 22,
-   18,  2, 14, 14, 14,  7, 10, 21, 17, 21, 11, 12,  5,  2,  5,  6,
-    8,  8,  8, 24,  5, 24,  2, 24,  9, 24, 24,  2, 29, 29, 29,  1,
-   17, 17, 20, 19, 22, 20, 27, 28,  1, 29, 21, 20, 19, 21, 21, 16,
-   16, 21, 25, 22, 18, 21, 21, 29,  1,  2, 15,  6, 18,  6, 23,  2,
-   12, 11,  9, 26, 26,  9, 26,  5,  5, 26, 14,  9,  5, 14, 14, 15,
-   25, 26, 26, 22, 18, 26, 18, 25, 18, 22,  5, 12,  2,  5, 22, 21,
-   21, 22, 18, 17, 26,  6,  7, 14, 17, 22, 18, 18, 26, 14, 17,  6,
-   14,  6, 12, 24, 24,  6, 26, 15,  6, 21, 11, 21, 24,  9,  6,  9,
-   23, 26,  6, 10,  4,  4,  3,  3,  7, 25, 17, 16, 16, 22, 16, 16,
-   25, 17, 25,  2, 25, 24,  2, 15, 12, 15, 14,  2, 21, 14,  7, 15,
-   12, 17, 21,  1, 26, 10, 10,  1, 23, 15,  0,  1,  2,  3,  4,  5,
-    6,  7,  8,  9,  0, 10, 11, 12, 13,  0, 14,  0,  0,  0,  0,  0,
-   15,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 18, 19,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 20,  0, 21, 22, 23,  0,  0,  0, 24,
-   25, 26, 27, 28, 29, 30, 31, 32, 33, 34,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 35,
-    0, 36,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,
-    0,  0, 38, 39,  0,  0,  0,  0,  0,  0, 40, 41, 42,  0, 43,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,
-    0,  0,  3,  0,  0,  0,  4,  5,  6,  7,  0,  8,  9, 10,  0, 11,
-   12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19,  0, 19,
-   16, 20, 16, 19, 21, 19,  0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-   31,  0, 32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33,  0,  0,
-    0,  0,  0,  0, 34,  0,  0, 35,  0,  0, 36,  0, 37,  0,  0,  0,
-   38, 39, 40, 41, 42, 43, 44, 45, 46,  0,  0, 47,  0,  0,  0, 48,
-    0,  0,  0, 49,  0,  0,  0,  0,  0,  0,  0, 50,  0, 51,  0, 52,
-   53,  0, 54,  0,  0,  0,  0,  0,  0, 55, 56, 57,  0,  0,  0,  0,
-   58,  0,  0, 59, 60, 61, 62, 63,  0,  0, 64, 65,  0,  0,  0, 66,
-    0,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 69,  0,  0,  0, 70,  0, 71,  0,  0,
-   72,  0,  0, 73,  0,  0,  0,  0,  0,  0,  0,  0, 74,  0,  0,  0,
-    0,  0, 75, 76,  0, 77, 78,  0,  0, 79, 80,  0, 81, 62,  0, 82,
-   83,  0,  0, 84, 85, 86,  0,  0,  0, 87,  0, 88,  0,  0, 51, 89,
-   51,  0, 90,  0, 91,  0,  0,  0, 80,  0,  0,  0, 92, 93,  0, 94,
-   95, 96, 97,  0,  0,  0,  0,  0, 51,  0,  0,  0,  0, 98, 99,  0,
-    0,  0,  0,  0,  0,100,  0,  0,  0,  0,  0,101,102,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,103,  0,  0,104,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,105,106,  0,  0,107,  0,  0,  0,  0,  0,  0,
-  108,  0,109,  0,102,  0,  0,  0,  0,  0,110,111,  0,  0,  0,  0,
-    0,  0,  0,112,  0,  0,  0,  0,  0,  0,  0,113,  0,114,  0,  0,
-    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  0,  8,  0,  0,  0,
-    0,  9, 10, 11, 12,  0,  0,  0,  0, 13,  0,  0, 14, 15,  0, 16,
-    0, 17, 18,  0,  0, 19,  0, 20, 21,  0,  0,  0,  0,  0, 22, 23,
-    0, 24, 25,  0,  0, 26,  0,  0,  0, 27,  0,  0, 28, 29, 30, 31,
-    0,  0,  0, 32, 33, 34,  0,  0, 33,  0,  0, 35, 33,  0,  0,  0,
-   33, 36,  0,  0,  0,  0,  0, 37, 38,  0,  0,  0,  0,  0,  0, 39,
-   40,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0, 43,  0, 44,
-    0,  0,  0, 45, 46,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0, 48,
-   49,  0,  0,  0,  0, 50,  0,  0,  0, 51,  0, 52,  0, 53,  0,  0,
-    0,  0, 54,  0,  0,  0,  0, 55,  0, 56,  0,  0,  0,  0, 57, 58,
-    0,  0,  0, 59, 60,  0,  0,  0,  0,  0,  0, 61, 52,  0, 62, 63,
-    0,  0, 64,  0,  0,  0, 65, 66,  0,  0,  0, 67,  0, 68, 69, 70,
-   71, 72,  1, 73,  0, 74, 75, 76,  0,  0, 77, 78,  0,  0,  0, 79,
-    0,  0,  1,  1,  0,  0, 80,  0,  0, 81,  0,  0,  0,  0, 77, 82,
-    0, 83,  0,  0,  0,  0,  0, 78, 84,  0, 85,  0, 52,  0,  1, 78,
-    0,  0, 86,  0,  0, 87,  0,  0,  0,  0,  0, 88, 57,  0,  0,  0,
-    0,  0,  0, 89, 90,  0,  0, 84,  0,  0, 33,  0,  0, 91,  0,  0,
-    0,  0, 92,  0,  0,  0,  0, 49,  0,  0, 93,  0,  0,  0,  0, 94,
-   95,  0,  0, 96,  0,  0, 97,  0,  0,  0, 98,  0,  0,  0, 99,  0,
-    0,  0,  0,100,101, 93,  0,  0,102,  0,  0,  0, 84,  0,  0,103,
-    0,  0,  0,104,105,  0,  0,106,107,  0,  0,  0,  0,  0,  0,108,
-    0,  0,109,  0,  0,  0,  0,110, 33,  0,111,112,113, 35,  0,  0,
-  114,  0,  0,  0,115,  0,  0,  0,  0,  0,  0,116,  0,  0,117,  0,
-    0,  0,  0,118, 88,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0, 52,
-  119,  0,  0,  0,  0,120,  0,  0,121,  0,  0,  0,  0,119,  0,  0,
-  122,  0,  0,  0,  0,  0,  0,123,  0,  0,  0,124,  0,  0,  0,125,
-    0,126,  0,  0,  0,  0,127,128,129,  0,130,  0,131,  0,  0,  0,
-  132,133,134,  0, 77,  0,  0,  0,  0,  0, 35,  0,  0,  0,135,  0,
-    0,  0,136,  0,  0,137,  0,  0,138,  0,  0,  0,  0,  0,  0,  0,
-    1,  1,  1,  1,  1,  2,  3,  4,  5,  6,  7,  4,  4,  8,  9, 10,
-    1, 11, 12, 13, 14, 15, 16, 17, 18,  1,  1,  1, 19,  1,  0,  0,
-   20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28, 29, 30,  0,  0,
-    1,  1, 31,  0,  0,  0, 32, 33, 34, 35,  1, 36, 37,  0,  0,  0,
-    0, 38,  1, 39, 14, 39, 40, 41, 42,  0,  0,  0, 43, 36, 44, 45,
-   21, 45, 46,  0,  0,  0, 19,  1, 21,  0,  0, 47,  0, 38, 48,  1,
-    1, 49, 49, 50,  0,  0, 51,  0,  0,  0, 52,  1,  0,  0, 38, 14,
-    4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,  0,  0,  0, 55,
-    0,  0,  0, 56, 57, 58,  0,  0,  0,  0,  0, 59,  0, 60,  0,  0,
-    0,  0, 61, 62,  0,  0, 63,  0,  0,  0, 64,  0,  0,  0, 65,  0,
-    0,  0, 66,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0, 69, 70,  0,
-   71, 72, 73, 74, 75, 76,  0,  0,  0, 77,  0,  0,  0, 78, 79,  0,
-    0,  0,  0, 47,  0,  0,  0, 49,  0, 80,  0,  0,  0, 62,  0,  0,
-   63,  0,  0, 81,  0,  0, 82,  0,  0,  0, 83,  0,  0, 19, 84,  0,
-   62,  0,  0,  0,  0, 49,  1, 85,  1, 52, 15, 86, 36, 10, 21, 87,
-    0, 55,  0,  0,  0,  0, 19, 10,  1,  0,  0,  0,  0,  0, 88,  0,
-    0, 89,  0,  0, 88,  0,  0,  0,  0, 78,  0,  0, 87,  9, 12,  4,
-   90,  8, 91, 47,  0, 58, 50,  0, 21,  1, 21, 92, 93,  1,  1,  1,
-    1, 94, 95, 96, 97,  1, 98, 58, 81, 99,100,  4, 58,  0,  0,  0,
-    0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0, 61,  0,  0,101,102,
-    0,  0,103,  0,  0,  1,  1, 50,  0,  0,  0, 38,  0, 63,  0,  0,
-    0,  0,  0, 62,  0,  0,104, 68, 61,  0,  0,  0, 78,  0,  0,  0,
-  105,106, 58, 38, 81,  0,  0,  0,  0,  0,  0,107,  1, 14,  4, 12,
-   84,  0,  0,  0,  0, 38, 87,  0,  0,  0,  0,108,  0,  0,109, 61,
-    0,110,  0,  0,  0,  1,  0,  0,  0,  0, 19, 58,  0,  0,  0, 51,
-    0,111, 14, 52,112, 41,  0,  0, 62,  0,  0, 61,  0,  0,113,  0,
-   87,  0,  0,  0, 61, 62,  0,  0, 62,  0, 89,  0,  0,113,  0,  0,
-    0,  0,114,  0,  0,  0, 78, 55,  0, 38,  1, 58,  1, 58,  0,  0,
-   63, 89,  0,  0,115,  0,  0,  0, 55,  0,  0,  0,  0,115,  0,  0,
-    0,  0, 61,  0,  0,  0,  0, 79,  0, 61,  0,  0,  0,  0, 56,  0,
-   89, 80,  0,  0, 79,  0,  0,  0,  8, 91,  0,  0,  1, 87,  0,  0,
-  116,  0,  0,  0,  0,  0,  0,117,  0,118,119,120,121,  0,104,  4,
-  122, 49, 23,  0,  0,  0, 38, 50, 38, 58,  0,  0,  1, 87,  1,  1,
-    1,  1, 39,  1, 48,105, 87,  0,  0,  0,  0,  1,  0,  0,  0,123,
-    4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,230,230,230,230,
-  230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
-  220,220,220,202,202,220,220,220,  1,  1,  1,  1,  1,220,220,220,
-  220,230,230,230,230,240,230,220,220,220,230,230,230,220,220,  0,
-  230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
-  234,234,233,230,  0,  0,  0,230,  0,220,230,230,230,230,220,230,
-  230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
-   14, 15, 16, 17, 18, 19, 19, 20, 21, 22,  0, 23,  0, 24, 25,  0,
-  230,220,  0, 18, 30, 31, 32,  0,  0,  0,  0, 27, 28, 29, 30, 31,
-   32, 33, 34,230,230,220,220,230,220,230,230,220, 35,  0,  0,  0,
-    0,  0,230,230,230,  0,  0,230,230,  0,220,230,230,220,  0,  0,
-    0, 36,  0,  0,230,220,230,230,220,220,230,220,220,230,220,230,
-  220,230,230,  0,  0,220,  0,  0,230,230,  0,230,  0,230,230,230,
-  230,230,  0,  0,  0,220,220,220,230,220,220,220,230,230,  0,220,
-   27, 28, 29,230,  7,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,
-  230,  0,  0,  0,  0,  0,230,  0,  0, 84, 91,  0,  0,  0,  0,  9,
-    9,  0,  0,  0,  0,  0,  9,  0,103,103,  9,  0,107,107,107,107,
-  118,118,  9,  0,122,122,122,122,220,220,  0,  0,  0,220,  0,220,
-    0,216,  0,  0,  0,129,130,  0,132,  0,  0,  0,  0,  0,130,130,
-  130,130,  0,  0,130,  0,230,230,  9,  0,230,230,  0,  0,220,  0,
-    0,  0,  0,  7,  0,  9,  9,  0,  9,  9,  0,  0,  0,230,  0,  0,
-    0,228,  0,  0,  0,222,230,220,220,  0,  0,  0,230,  0,  0,220,
-  230,220,  0,220,230,230,230,  0,  0,  0,  9,  9,  0,  0,  7,  0,
-  230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,202,230,230,230,
-  230,230,232,228,228,220,218,230,233,220,230,220,230,230,  1,  1,
-    1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,  0,  0,218,228,
-  232,222,224,224,  0,  8,  8,  0,  0,  0,  0,220,230,  0,230,230,
-  220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,
-    0,230,220,  0,  0,  0,220,220,  0,  0,230,220,  0,  9,  7,  0,
-    0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,  0,  0,  1,  0,
-    0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,
-  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 33,
-   17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17,
+    8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
+   55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67,
+   67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67,
+   67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44,
+   67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41,
+   67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67,
+   67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55,
+   67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67,
+   79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44,
+  171,171,171,171,171,171,171,  0,  0,  0, 29, 21, 21, 21, 23, 21,
+   22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21,  9,  9,  9,
+    9, 22, 21, 18, 24, 16, 24,  5,  5,  5,  5, 22, 25, 18, 25,  0,
+   23, 23, 26, 21, 24, 26,  7, 20, 25,  1, 26, 24, 26, 25, 15, 15,
+   24, 15,  7, 19, 15, 21,  9, 25,  9,  5,  5, 25,  5,  9,  5,  7,
+    7,  7,  9,  8,  8,  5,  7,  5,  6,  6, 24, 24,  6, 24, 12, 12,
+    2,  2,  6,  5,  9, 21,  9,  2,  2,  9, 25,  9, 26, 12, 11, 11,
+    2,  6,  5, 21, 17,  2,  2, 26, 26, 23,  2, 12, 17, 12, 21, 12,
+   12, 21,  7,  2,  2,  7,  7, 21, 21,  2,  1,  1, 21, 23, 26, 26,
+    1, 21,  6,  7,  7, 12, 12,  7, 21,  7, 12,  1, 12,  6,  6, 12,
+   12, 26,  7, 26, 26,  7,  2,  1, 12,  2,  6,  2, 24,  7,  7,  6,
+    1, 12, 12, 10, 10, 10, 10, 12, 21,  6,  2, 10, 10,  2, 15, 26,
+   26,  2,  2, 21,  7, 10, 15,  7,  2, 23, 21, 26, 10,  7, 21, 15,
+   15,  2, 17,  7, 29,  7,  7, 22, 18,  2, 14, 14, 14,  7, 10, 21,
+   17, 21, 11, 12,  5,  2,  5,  6,  8,  8,  8, 24,  5, 24,  2, 24,
+    9, 24, 24,  2, 29, 29, 29,  1, 17, 17, 20, 19, 22, 20, 27, 28,
+    1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29,
+    1,  2, 15,  6, 18,  6, 23,  2, 12, 11,  9, 26, 26,  9, 26,  5,
+    5, 26, 14,  9,  5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25,
+   18, 22,  5, 12,  2,  5, 22, 21, 21, 22, 18, 17, 26,  6,  7, 14,
+   17, 22, 18, 18, 26, 14, 17,  6, 14,  6, 12, 24, 24,  6, 26, 15,
+    6, 21, 11, 21, 24,  9,  6,  9, 23, 26,  6, 10,  4,  4,  3,  3,
+    7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25,  2, 25, 24,  2, 15,
+   12, 15, 14,  2, 21, 14,  7, 15, 12, 17, 21,  1, 26, 10, 10,  1,
+   23, 15,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0, 10, 11, 12,
+   13,  0, 14,  0,  0,  0,  0,  0, 15,  0, 16,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,
+    0, 21, 22, 23,  0,  0,  0, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+   33, 34,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 35,  0, 36,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,
+    0,  0, 40, 41, 42,  0, 43,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  3,  0,  0,  0,  4,  5,
+    6,  7,  0,  8,  9, 10,  0, 11, 12, 13, 14, 15, 16, 17, 16, 18,
+   16, 19, 16, 19, 16, 19,  0, 19, 16, 20, 16, 19, 21, 19,  0, 22,
+   23, 24, 25, 26, 27, 28, 29, 30, 31,  0, 32,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 33,  0,  0,  0,  0,  0,  0, 34,  0,  0, 35,
+    0,  0, 36,  0, 37,  0,  0,  0, 38, 39, 40, 41, 42, 43, 44, 45,
+   46,  0,  0, 47,  0,  0,  0, 48,  0,  0,  0, 49,  0,  0,  0,  0,
+    0,  0,  0, 50,  0, 51,  0, 52, 53,  0, 54,  0,  0,  0,  0,  0,
+    0, 55, 56, 57,  0,  0,  0,  0, 58,  0,  0, 59, 60, 61, 62, 63,
+    0,  0, 64, 65,  0,  0,  0, 66,  0,  0,  0,  0, 67,  0,  0,  0,
+   68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 69,
+    0,  0,  0, 70,  0, 71,  0,  0, 72,  0,  0, 73,  0,  0,  0,  0,
+    0,  0,  0,  0, 74,  0,  0,  0,  0,  0, 75, 76,  0, 77, 78,  0,
+    0, 79, 80,  0, 81, 62,  0, 82, 83,  0,  0, 84, 85, 86,  0,  0,
+    0, 87,  0, 88,  0,  0, 51, 89, 51,  0, 90,  0, 91,  0,  0,  0,
+   80,  0,  0,  0, 92, 93,  0, 94, 95, 96, 97,  0,  0,  0,  0,  0,
+   51,  0,  0,  0,  0, 98, 99,  0,  0,  0,  0,  0,  0,100,  0,  0,
+    0,  0,  0,101,102,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,103,
+    0,  0,104,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,106,  0,
+    0,107,  0,  0,  0,  0,  0,  0,108,  0,109,  0,102,  0,  0,  0,
+    0,  0,110,111,  0,  0,  0,  0,  0,  0,  0,112,  0,  0,  0,  0,
+    0,  0,  0,113,  0,114,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  0,  8,  0,  0,  0,  0,  9, 10, 11, 12,  0,  0,  0,
+    0, 13,  0,  0, 14, 15,  0, 16,  0, 17, 18,  0,  0, 19,  0, 20,
+   21,  0,  0,  0,  0,  0, 22, 23,  0, 24, 25,  0,  0, 26,  0,  0,
+    0, 27,  0,  0, 28, 29, 30, 31,  0,  0,  0, 32, 33, 34,  0,  0,
+   33,  0,  0, 35, 33,  0,  0,  0, 33, 36,  0,  0,  0,  0,  0, 37,
+   38,  0,  0,  0,  0,  0,  0, 39, 40,  0,  0,  0,  0,  0,  0, 41,
+   42,  0,  0,  0,  0, 43,  0, 44,  0,  0,  0, 45, 46,  0,  0,  0,
+   47,  0,  0,  0,  0,  0,  0, 48, 49,  0,  0,  0,  0, 50,  0,  0,
+    0, 51,  0, 52,  0, 53,  0,  0,  0,  0, 54,  0,  0,  0,  0, 55,
+    0, 56,  0,  0,  0,  0, 57, 58,  0,  0,  0, 59, 60,  0,  0,  0,
+    0,  0,  0, 61, 52,  0, 62, 63,  0,  0, 64,  0,  0,  0, 65, 66,
+    0,  0,  0, 67,  0, 68, 69, 70, 71, 72,  1, 73,  0, 74, 75, 76,
+    0,  0, 77, 78,  0,  0,  0, 79,  0,  0,  1,  1,  0,  0, 80,  0,
+    0, 81,  0,  0,  0,  0, 77, 82,  0, 83,  0,  0,  0,  0,  0, 78,
+   84,  0, 85,  0, 52,  0,  1, 78,  0,  0, 86,  0,  0, 87,  0,  0,
+    0,  0,  0, 88, 57,  0,  0,  0,  0,  0,  0, 89, 90,  0,  0, 84,
+    0,  0, 33,  0,  0, 91,  0,  0,  0,  0, 92,  0,  0,  0,  0, 49,
+    0,  0, 93,  0,  0,  0,  0, 94, 95,  0,  0, 96,  0,  0, 97,  0,
+    0,  0, 98,  0,  0,  0, 99,  0,  0,  0,  0,100,101, 93,  0,  0,
+  102,  0,  0,  0, 84,  0,  0,103,  0,  0,  0,104,105,  0,  0,106,
+  107,  0,  0,  0,  0,  0,  0,108,  0,  0,109,  0,  0,  0,  0,110,
+   33,  0,111,112,113, 35,  0,  0,114,  0,  0,  0,115,  0,  0,  0,
+    0,  0,  0,116,  0,  0,117,  0,  0,  0,  0,118, 88,  0,  0,  0,
+    0,  0, 57,  0,  0,  0,  0, 52,119,  0,  0,  0,  0,120,  0,  0,
+  121,  0,  0,  0,  0,119,  0,  0,122,  0,  0,  0,  0,  0,  0,123,
+    0,  0,  0,124,  0,  0,  0,125,  0,126,  0,  0,  0,  0,127,128,
+  129,  0,130,  0,131,  0,  0,  0,132,133,134,  0, 77,  0,  0,  0,
+    0,  0, 35,  0,  0,  0,135,  0,  0,  0,136,  0,  0,137,  0,  0,
+  138,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  3,  4,
+    5,  6,  7,  4,  4,  8,  9, 10,  1, 11, 12, 13, 14, 15, 16, 17,
+   18,  1,  1,  1, 19,  1,  0,  0, 20, 21, 22,  1, 23,  4, 21, 24,
+   25, 26, 27, 28, 29, 30,  0,  0,  1,  1, 31,  0,  0,  0, 32, 33,
+   34, 35,  1, 36, 37,  0,  0,  0,  0, 38,  1, 39, 14, 39, 40, 41,
+   42,  0,  0,  0, 43, 36, 44, 45, 21, 45, 46,  0,  0,  0, 19,  1,
+   21,  0,  0, 47,  0, 38, 48,  1,  1, 49, 49, 50,  0,  0, 51,  0,
+    0,  0, 52,  1,  0,  0, 38, 14,  4,  1,  1,  1, 53, 21, 43, 52,
+   54, 21, 35,  1,  0,  0,  0, 55,  0,  0,  0, 56, 57, 58,  0,  0,
+    0,  0,  0, 59,  0, 60,  0,  0,  0,  0, 61, 62,  0,  0, 63,  0,
+    0,  0, 64,  0,  0,  0, 65,  0,  0,  0, 66,  0,  0,  0, 67,  0,
+    0,  0, 68,  0,  0, 69, 70,  0, 71, 72, 73, 74, 75, 76,  0,  0,
+    0, 77,  0,  0,  0, 78, 79,  0,  0,  0,  0, 47,  0,  0,  0, 49,
+    0, 80,  0,  0,  0, 62,  0,  0, 63,  0,  0, 81,  0,  0, 82,  0,
+    0,  0, 83,  0,  0, 19, 84,  0, 62,  0,  0,  0,  0, 49,  1, 85,
+    1, 52, 15, 86, 36, 10, 21, 87,  0, 55,  0,  0,  0,  0, 19, 10,
+    1,  0,  0,  0,  0,  0, 88,  0,  0, 89,  0,  0, 88,  0,  0,  0,
+    0, 78,  0,  0, 87,  9, 12,  4, 90,  8, 91, 47,  0, 58, 50,  0,
+   21,  1, 21, 92, 93,  1,  1,  1,  1, 94, 95, 96, 97,  1, 98, 58,
+   81, 99,100,  4, 58,  0,  0,  0,  0,  0,  0, 19, 50,  0,  0,  0,
+    0,  0,  0, 61,  0,  0,101,102,  0,  0,103,  0,  0,  1,  1, 50,
+    0,  0,  0, 38,  0, 63,  0,  0,  0,  0,  0, 62,  0,  0,104, 68,
+   61,  0,  0,  0, 78,  0,  0,  0,105,106, 58, 38, 81,  0,  0,  0,
+    0,  0,  0,107,  1, 14,  4, 12, 84,  0,  0,  0,  0, 38, 87,  0,
+    0,  0,  0,108,  0,  0,109, 61,  0,110,  0,  0,  0,  1,  0,  0,
+    0,  0, 19, 58,  0,  0,  0, 51,  0,111, 14, 52,112, 41,  0,  0,
+   62,  0,  0, 61,  0,  0,113,  0, 87,  0,  0,  0, 61, 62,  0,  0,
+   62,  0, 89,  0,  0,113,  0,  0,  0,  0,114,  0,  0,  0, 78, 55,
+    0, 38,  1, 58,  1, 58,  0,  0, 63, 89,  0,  0,115,  0,  0,  0,
+   55,  0,  0,  0,  0,115,  0,  0,  0,  0, 61,  0,  0,  0,  0, 79,
+    0, 61,  0,  0,  0,  0, 56,  0, 89, 80,  0,  0, 79,  0,  0,  0,
+    8, 91,  0,  0,  1, 87,  0,  0,116,  0,  0,  0,  0,  0,  0,117,
+    0,118,119,120,121,  0,104,  4,122, 49, 23,  0,  0,  0, 38, 50,
+   38, 58,  0,  0,  1, 87,  1,  1,  1,  1, 39,  1, 48,105, 87,  0,
+    0,  0,  0,  1,  0,  0,  0,123,  4,122,  0,  0,  0,  1,124,  0,
+    0,  0,  0,  0,230,230,230,230,230,232,220,220,220,220,232,216,
+  220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,
+    1,  1,  1,  1,  1,220,220,220,220,230,230,230,230,240,230,220,
+  220,220,230,230,230,220,220,  0,230,230,230,220,220,220,220,230,
+  232,220,220,230,233,234,234,233,234,234,233,230,  0,  0,  0,230,
+    0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220,
+  230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
+   21, 22,  0, 23,  0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,
+    0,  0,  0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,
+  220,230,230,220, 35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,
+  230,  0,220,230,230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,
+  220,220,230,220,220,230,220,230,220,230,230,  0,  0,220,  0,  0,
+  230,230,  0,230,  0,230,230,230,230,230,  0,  0,  0,220,220,220,
+  230,220,220,220,230,230,  0,220, 27, 28, 29,230,  7,  0,  0,  0,
+    0,  9,  0,  0,  0,230,220,230,230,  0,  0,  0,  0,  0,230,  0,
+    0, 84, 91,  0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  9,  0,
+  103,103,  9,  0,107,107,107,107,118,118,  9,  0,122,122,122,122,
+  220,220,  0,  0,  0,220,  0,220,  0,216,  0,  0,  0,129,130,  0,
+  132,  0,  0,  0,  0,  0,130,130,130,130,  0,  0,130,  0,230,230,
+    9,  0,230,230,  0,  0,220,  0,  0,  0,  0,  7,  0,  9,  9,  0,
+    9,  9,  0,  0,  0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,
+  220,  0,  0,  0,230,  0,  0,220,230,220,  0,220,230,230,230,  0,
+    0,  0,  9,  9,  0,  0,  7,  0,230,  0,  1,  1,  1,  0,  0,  0,
+  230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230,
+  233,220,230,220,230,230,  1,  1,  1,  1,  1,230,  0,  1,  1,230,
+  220,230,  1,  1,  0,  0,218,228,232,222,224,224,  0,  8,  8,  0,
+    0,  0,  0,220,230,  0,230,230,220,  0,  0,230,  0,  0, 26,  0,
+    0,220,  0,230,230,  1,220,  0,  0,230,220,  0,  0,  0,220,220,
+    0,  0,230,220,  0,  9,  7,  0,  0,  7,  9,  0,  0,  0,  9,  7,
+    6,  6,  0,  0,  0,  0,  1,  0,  0,216,216,  1,  1,  1,  0,  0,
+    0,226,216,216,216,216,216,  0,220,220,220,  0,232,232,220,230,
+  230,230,  7,  0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145,
+   26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177,  0,  1,  2,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
-    4,  3,  3,  3,  3,  3,  5,  3,  3,  3,  3,  3,  6,  7,  8,  3,
-    3,  3,  3,  3,  9, 10, 11, 12, 13,  3,  3,  3,  3,  3,  3,  3,
-    3, 14,  3, 15,  3,  3,  3,  3,  3,  3, 16, 17, 18, 19, 20, 21,
-    3,  3,  3, 22, 23, 24,  3,  3,  3,  3,  3,  3, 25,  3,  3,  3,
-    3,  3,  3,  3,  3, 26,  3,  3, 27, 28,  0,  1,  0,  0,  0,  0,
-    0,  1,  0,  2,  0,  0,  0,  3,  0,  0,  0,  3,  0,  0,  0,  0,
-    0,  4,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  6,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  8,  9,  0,  0,  0,  0,  0,  0,  9,  0,  9,  0,  0,
-    0,  0,  0,  0,  0, 10, 11, 12, 13,  0,  0, 14, 15, 16,  6,  0,
-   17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25,  0, 26, 27, 19,
-   19, 28, 29, 30,  0, 31,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,
-    0, 19, 28,  0, 32, 33,  9, 34, 35, 19,  0,  0, 36, 37, 38, 39,
-   40, 19,  0, 41, 42, 43, 44, 31,  0,  1, 45, 42,  0,  0,  0,  0,
-    0, 32, 14, 14,  0,  0,  0,  0, 14,  0,  0, 46, 47, 47, 47, 47,
-   48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21,  0,  0,  0,  0,
-    0,  0,  0, 54,  6, 55,  0, 14, 19,  1,  0,  0,  0,  0, 56, 57,
-    0,  0,  0,  0,  0, 19, 58, 31,  0,  0,  0,  0,  0,  0,  0, 59,
-   14,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  3,  0,  0,  0, 60,
-   61,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  2,  3,
-    0,  4,  5,  0,  0,  6,  0,  0,  0,  7,  0,  0,  0,  1,  1,  0,
-    0,  8,  9,  0,  8,  9,  0,  0,  0,  0,  8,  9, 10, 11, 12,  0,
-    0,  0, 13,  0,  0,  0,  0, 14, 15, 16, 17,  0,  0,  0,  1,  0,
-    0, 18, 19,  0,  0,  0, 20,  0,  0,  0,  1,  1,  1,  1,  0,  1,
-    1,  1,  1,  1,  1,  1,  0,  8, 21,  9,  0,  0, 22,  0,  0,  0,
-    0,  1,  0, 23, 24, 25,  0,  0, 26,  0,  0,  0,  8, 21, 27,  0,
-    1,  0,  0,  1,  1,  1,  1,  0,  1, 28, 29, 30,  0, 31, 32, 20,
-    1,  1,  0,  0,  0,  8, 21,  9,  1,  4,  5,  0,  0,  0, 33,  9,
-    0,  1,  1,  1,  0,  8, 21, 21, 21, 21, 34,  1, 35, 21, 21, 21,
-    9, 36,  0,  0, 37, 38,  1,  0, 39,  0,  0,  0,  1,  0,  1,  0,
-    0,  0,  0,  8, 21,  9,  1,  0,  0,  0, 40,  0,  8, 21, 21, 21,
-   21, 21, 21, 21, 21,  9,  0,  1,  1,  1,  1,  8, 21, 21, 21,  9,
-    0,  0,  0, 41,  0, 42, 43,  0,  0,  0,  1, 44,  0,  0,  0, 45,
-    8,  9,  1,  0,  0,  0,  8, 21, 21, 21,  9,  0,  1,  0,  1,  1,
-    8, 21, 21,  9,  0,  4,  5,  8,  9,  1,  0,  0,  0,  1,  2,  3,
-    4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-    9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
-   19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
-   13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36,  7,  7,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-   37,  7, 38, 39,  7, 40,  7,  7,  7, 41, 13, 42,  7,  7, 43,  7,
-   44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   17, 17, 17,177,  0,  1,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  4,  3,  3,  3,  3,  3,  5,  3,
+    3,  3,  3,  3,  6,  7,  8,  3,  3,  3,  3,  3,  9, 10, 11, 12,
+   13,  3,  3,  3,  3,  3,  3,  3,  3, 14,  3, 15,  3,  3,  3,  3,
+    3,  3, 16, 17, 18, 19, 20, 21,  3,  3,  3, 22, 23, 24,  3,  3,
+    3,  3,  3,  3, 25,  3,  3,  3,  3,  3,  3,  3,  3, 26,  3,  3,
+   27, 28,  0,  1,  0,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  3,
+    0,  0,  0,  3,  0,  0,  0,  0,  0,  4,  0,  5,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  7,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,
+    0,  0,  0,  9,  0,  9,  0,  0,  0,  0,  0,  0,  0, 10, 11, 12,
+   13,  0,  0, 14, 15, 16,  6,  0, 17, 18, 19, 19, 19, 20, 21, 22,
+   23, 24, 19, 25,  0, 26, 27, 19, 19, 28, 29, 30,  0, 31,  0,  0,
+    0,  8,  0,  0,  0,  0,  0,  0,  0, 19, 28,  0, 32, 33,  9, 34,
+   35, 19,  0,  0, 36, 37, 38, 39, 40, 19,  0, 41, 42, 43, 44, 31,
+    0,  1, 45, 42,  0,  0,  0,  0,  0, 32, 14, 14,  0,  0,  0,  0,
+   14,  0,  0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51,
+   52, 53, 43, 21,  0,  0,  0,  0,  0,  0,  0, 54,  6, 55,  0, 14,
+   19,  1,  0,  0,  0,  0, 56, 57,  0,  0,  0,  0,  0, 19, 58, 31,
+    0,  0,  0,  0,  0,  0,  0, 59, 14,  0,  0,  0,  0,  1,  0,  2,
+    0,  0,  0,  3,  0,  0,  0, 60, 61,  0,  0,  0,  0,  0,  0,  0,
+    1,  0,  0,  0,  0,  0,  2,  3,  0,  4,  5,  0,  0,  6,  0,  0,
+    0,  7,  0,  0,  0,  1,  1,  0,  0,  8,  9,  0,  8,  9,  0,  0,
+    0,  0,  8,  9, 10, 11, 12,  0,  0,  0, 13,  0,  0,  0,  0, 14,
+   15, 16, 17,  0,  0,  0,  1,  0,  0, 18, 19,  0,  0,  0, 20,  0,
+    0,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  0,  8,
+   21,  9,  0,  0, 22,  0,  0,  0,  0,  1,  0, 23, 24, 25,  0,  0,
+   26,  0,  0,  0,  8, 21, 27,  0,  1,  0,  0,  1,  1,  1,  1,  0,
+    1, 28, 29, 30,  0, 31, 32, 20,  1,  1,  0,  0,  0,  8, 21,  9,
+    1,  4,  5,  0,  0,  0, 33,  9,  0,  1,  1,  1,  0,  8, 21, 21,
+   21, 21, 34,  1, 35, 21, 21, 21,  9, 36,  0,  0, 37, 38,  1,  0,
+   39,  0,  0,  0,  1,  0,  1,  0,  0,  0,  0,  8, 21,  9,  1,  0,
+    0,  0, 40,  0,  8, 21, 21, 21, 21, 21, 21, 21, 21,  9,  0,  1,
+    1,  1,  1,  8, 21, 21, 21,  9,  0,  0,  0, 41,  0, 42, 43,  0,
+    0,  0,  1, 44,  0,  0,  0, 45,  8,  9,  1,  0,  0,  0,  8, 21,
+   21, 21,  9,  0,  1,  0,  1,  1,  8, 21, 21,  9,  0,  4,  5,  8,
+    9,  1,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  9, 10, 11, 11, 11, 11, 12, 13,
+   13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13,
+   13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32,
+   33, 34, 35, 36,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7, 37,  7, 38, 39,  7, 40,  7,  7,
+    7, 41, 13, 42,  7,  7, 43,  7, 44, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -3479,221 +3481,221 @@
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45,  0,  0,  1,
-    2,  2,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-   32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
-   43, 44, 45, 46, 47, 48, 49, 50, 51, 52,  2,  2, 53, 54, 55, 56,
-   57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
-   59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
-   74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   13, 13, 13, 13, 45,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
+   37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+   51, 52,  2,  2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
+   59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
+   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
-   80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
-   89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81,
+   82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
-  110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
-  124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
-  139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
-  152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
-  164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
-  169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
-  173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,
+  102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116,
+  117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131,
+  132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145,
+   96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158,
+  159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164,
+  167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171,
+  171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96,
+   96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182,
   182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
-  182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
-  190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
-  198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
-  208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
-  213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
-  219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
-   59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
-   59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
+  182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185,
+  186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204,
+  205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96,
+   96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215,
+   96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221,
+  222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59,
+   59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96,
+   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
-   70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96,
-  246,247,  0,  1,  2,  2,  0,  1,  2,  2,  2,  3,  4,  5,  0,  0,
-    0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  0,  0,  0,
-   19,  0, 19,  0,  0,  0,  0,  0, 26, 26,  1,  1,  1,  1,  9,  9,
-    9,  9,  0,  9,  9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,
-    2,  2,  9,  0,  9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,
-    2,  9,  9,  9, 55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  1,
-    1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2, 14,
-   14, 14, 14, 14, 14, 14, 14, 14, 14,  2,  2,  2,  2, 14, 14,  2,
-    2,  2,  3,  3,  3,  3,  3,  0,  3,  3,  0,  3,  3,  3,  3,  3,
-    3,  0,  3,  3,  3,  1,  1,  1,  3,  3,  1,  3,  3,  3, 37, 37,
-   37, 37, 37, 37,  2, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38,
-   38, 38, 38, 38,  2,  2, 64, 64, 64, 64, 64, 64, 64,  2,  2, 64,
-   64, 64, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90, 90,  2, 95, 95,
-   95, 95,  2,  2, 95,  2,  3,  3,  3,  2,  3,  3,  2,  2,  3,  3,
-    0,  3,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  0,  0,
-    7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  2,  2,  5,  5,  2,
-    5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,
-    5,  2,  2,  2,  2,  5,  5,  5,  2,  5,  2, 11, 11, 11, 11, 11,
-   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11,  2,
-   11, 11,  2, 11, 11,  2, 11, 11,  2,  2,  2, 11,  2,  2, 11,  2,
-   11,  2,  2,  2, 11, 11,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-    2, 10, 10,  2, 10, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,
-   10, 10,  2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,
-   21, 21, 21, 21,  2,  2, 21, 21,  2, 21,  2,  2, 21, 21,  2,  2,
-   22, 22,  2, 22, 22, 22, 22, 22, 22,  2, 22,  2, 22, 22, 22, 22,
-    2,  2,  2, 22, 22,  2,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22,
-   22, 22, 23, 23, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2, 23,
-   23,  2, 23, 23, 23,  2,  2, 23,  2,  2,  2,  2, 23, 23,  2,  2,
-    2, 23, 16, 16, 16, 16, 16,  2, 16, 16,  2, 16, 16, 16, 16, 16,
-    2,  2,  2, 16, 16,  2,  2,  2, 16, 16, 20, 20, 20, 20, 20,  2,
-   20, 20,  2,  2, 20, 20,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-   36,  2,  2,  2, 36, 36, 36, 36,  2, 36,  2, 36,  2,  2,  2,  2,
-   36,  2,  2,  2,  2, 36, 36,  2, 36,  2, 36,  2,  2,  2,  2, 24,
-   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0,  2, 18,
-   18,  2, 18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18,  2, 18,
-    2, 18, 18, 18,  2,  2, 18,  2, 18,  2, 25, 25, 25, 25,  2, 25,
-   25, 25, 25,  2,  2,  2, 25,  2, 25, 25, 25,  0,  0,  0,  0, 25,
-   25,  2, 33, 33, 33, 33,  8,  8,  8,  8,  8,  8,  2,  8,  2,  8,
-    2,  2,  8,  8,  8,  0, 12, 12, 12, 12, 30, 30, 30, 30, 30,  2,
-   30, 30, 30, 30,  2,  2, 30, 30, 30,  2,  2, 30, 30, 30, 30,  2,
-    2,  2, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 34, 34,
-   34, 34, 34,  2,  2,  2, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0,
-   35, 35, 35,  2,  2,  2, 45, 45, 45, 45, 45, 45,  2,  2,  2,  2,
-    2, 45, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43, 43, 43, 46, 46,
-   46, 46, 46,  2, 46, 46, 31, 31, 31, 31, 31, 31,  2,  2, 32, 32,
-    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32,  2,  2, 32,  2,
-    2,  2, 32, 32, 32,  2, 28, 28,  2,  2, 48, 48, 48, 48, 48, 48,
-   48,  2, 48,  2,  2,  2, 52, 52, 52, 52, 52, 52,  2,  2, 52,  2,
-    2,  2, 58, 58, 58, 58, 58, 58,  2,  2, 58, 58, 58,  2,  2,  2,
-   58, 58, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91,
-   91,  2, 91,  2,  2, 91, 91, 91,  2,  2,  1,  1,  1,  2, 62, 62,
-   62, 62, 62,  2,  2,  2, 62, 62, 62,  2, 76, 76, 76, 76, 93, 93,
-   93, 93, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70,  2,  2,  2, 70,
-   70, 70, 73, 73, 73, 73,  6,  2,  2,  2,  8,  8,  8,  2,  2,  8,
-    8,  8,  1,  1,  1,  0,  1,  0,  1,  1,  1,  0,  0,  0,  0,  1,
-    0,  0,  1,  1,  0,  2, 19, 19,  9,  9,  9,  9,  9,  6, 19,  9,
-    9,  9,  9,  9, 19, 19,  9,  9,  9, 19,  6, 19, 19, 19, 19, 19,
-   19,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  9,  9,  1,  1,
-    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0, 19,  0,  0,
-    0,  2, 19,  2,  2,  2,  0,  2,  2,  2,  1,  2,  2,  2,  0,  0,
-    9,  0,  0,  0, 19, 19, 27, 27, 27, 27,  2,  2,  0,  0,  0,  0,
-    2,  0, 56, 56, 56, 56,  2, 55, 55, 55, 61, 61, 61, 61,  2,  2,
-    2, 61, 61,  2,  2,  2,  0,  0,  2,  2, 13, 13, 13, 13, 13, 13,
-    2, 13, 13, 13,  2,  2,  0, 13,  0, 13,  0, 13, 13, 13, 13, 13,
-    1,  1,  1,  1, 12, 12,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15,  2,  2,  1,  1,  0,  0, 15, 15, 15,  0, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17,  0,  2, 26, 26, 26, 26, 26, 26, 26,  2, 12,
-   12, 12, 12, 12, 12,  2, 12, 12, 12,  0, 39, 39, 39, 39, 39,  2,
-    2,  2, 39, 39, 39,  2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79,
-   79, 79, 19, 19, 19,  2, 19, 19,  2, 19,  2, 19, 19, 19, 19, 19,
-    2,  2,  2,  2, 19, 19, 60, 60, 60, 60, 60,  2,  2,  2, 65, 65,
-   65, 65, 75, 75, 75, 75, 75, 75,  2,  2,  2,  2, 75, 75, 69, 69,
-   69, 69, 69, 69,  0, 69, 74, 74, 74, 74,  2,  2,  2, 74, 12,  2,
-    2,  2, 84, 84, 84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2,
-   84, 84, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68, 68,  2, 68, 68,
-    2,  2, 92, 92, 92, 92, 92, 92, 92,  2,  2,  2,  2, 92, 87, 87,
-   87, 87, 87, 87, 87,  2, 19,  9, 19, 19, 19, 19,  0,  0, 87, 87,
-    2,  2,  2,  2,  2, 12,  2,  2,  2,  4, 14,  2, 14,  2, 14, 14,
-    2, 14, 14,  2, 14, 14,  2,  2,  2,  3,  3,  3,  0,  0,  2,  2,
-    3,  3,  1,  1,  6,  6,  3,  2,  3,  3,  3,  2,  2,  0,  2,  0,
-    0,  0,  0,  0, 17, 17, 17, 17,  0,  0,  2,  2, 12, 12, 49, 49,
-   49, 49,  2, 49, 49, 49, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49,
-    2,  2,  9,  2,  2,  2,  0,  1,  2,  2, 71, 71, 71, 71, 71,  2,
-    2,  2, 67, 67, 67, 67, 67,  2,  2,  2, 42, 42, 42, 42,  2, 42,
-   42, 42, 41, 41, 41, 41, 41, 41, 41,  2,118,118,118,118,118,118,
-  118,  2, 53, 53, 53, 53, 53, 53,  2, 53, 59, 59, 59, 59, 59, 59,
-    2,  2, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50,
-    2,  2,135,135,135,135,106,106,106,106,104,104,104,104,  2,  2,
-    2,104,161,161,161,161,161,161,161,  2,161,161,  2,161,161,  2,
-    2,  2,110,110,110,110,110,110,110,  2,110,110,  2,  2, 19,  2,
-   19, 19, 47, 47, 47, 47, 47, 47,  2,  2, 47,  2, 47, 47, 47, 47,
-    2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81, 81, 81, 81, 81,
-    2, 81,120,120,120,120,116,116,116,116,116,116,116,  2,  2,  2,
-    2,116,128,128,128,128,128,128,128,  2,128,128,  2,  2,  2,  2,
-    2,128, 66, 66, 66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72,
-    2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 97, 97, 97, 97,  2,  2,
-   97, 97, 57, 57, 57, 57,  2, 57, 57,  2,  2, 57, 57, 57, 57, 57,
-    2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57,  2,  2,  2, 88, 88,
-   88, 88,117,117,117,117,112,112,112,112,112,112,112,  2,  2,  2,
-    2,112, 78, 78, 78, 78, 78, 78,  2,  2,  2, 78, 78, 78, 83, 83,
-   83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82, 82,  2,122,122,
-  122,122,122,122,  2,  2,  2,122,122,122,122,  2,  2,  2, 89, 89,
-   89, 89, 89,  2,  2,  2,130,130,130,130,130,130,130,  2,  2,  2,
-  130,130,144,144,144,144,144,144,  2,  2,156,156,156,156,156,156,
-    2,156,156,156,  2,  2,  2,  3,  3,  3,147,147,147,147,148,148,
-  148,148,148,148,  2,  2,158,158,158,158,158,158,  2,  2,153,153,
-  153,153,149,149,149,149,149,149,149,  2, 94, 94, 94, 94, 94, 94,
-    2,  2,  2,  2, 94, 94,  2,  2,  2, 94, 85, 85, 85, 85, 85, 85,
-   85,  2,  2, 85,  2,  2,101,101,101,101,101,  2,  2,  2,101,101,
-    2,  2, 96, 96, 96, 96, 96,  2, 96, 96,111,111,111,111,111,111,
-  111,  2,100,100,100,100,108,108,108,108,108,108,  2,108,108,108,
-    2,  2,129,129,129,129,129,129,129,  2,129,  2,129,129,129,129,
-    2,129,129,129,  2,  2,109,109,109,109,109,109,109,  2,109,109,
-    2,  2,107,107,107,107,  2,107,107,107,107,  2,  2,107,107,  2,
-  107,107,107,107,  2,  1,107,107,  2,  2,107,  2,  2,  2,  2,  2,
-    2,107,  2,  2,107,107,137,137,137,137,  2,137,137,137,137,137,
-    2,  2,124,124,124,124,124,124,  2,  2,123,123,123,123,123,123,
-    2,  2,114,114,114,114,114,  2,  2,  2,114,114,  2,  2,102,102,
-  102,102,102,102,  2,  2,126,126,126,126,126,126,126,  2,  2,126,
-  126,126,142,142,142,142,125,125,125,125,125,125,125,  2,  2,  2,
-    2,125,154,154,154,154,154,154,154,  2,  2,154,  2,  2,  2,154,
-  154,  2,154,154,  2,154,154,  2,  2,154,154,154,  2,  2,150,150,
-  150,150,  2,  2,150,150,150,  2,  2,  2,141,141,141,141,140,140,
-  140,140,140,140,140,  2,121,121,121,121,121,  2,  2,  2,  7,  7,
-    2,  2,133,133,133,133,133,  2,133,133,133,133,133,  2,133,133,
-    2,  2,133,  2,  2,  2,134,134,134,134,  2,  2,134,134,  2,134,
-  134,134,134,134,134,  2,138,138,138,138,138,138,138,  2,138,138,
-    2,138,  2,  2,138,  2,138,138,  2,  2,143,143,143,143,143,143,
-    2,143,143,  2,143,143,143,143,143,  2,143,  2,  2,  2,143,143,
-    2,  2,145,145,145,145,145,  2,  2,  2,163,163,163,163,163,  2,
-  163,163,163,163,163,  2,  2,  2,163,163,163,163,  2,  2, 86,  2,
-    2,  2, 63, 63, 63, 63, 63, 63,  2,  2, 63, 63, 63,  2, 63,  2,
-    2,  2,157,157,157,157,157,157,157,  2, 80, 80, 80, 80, 80, 80,
-    2,  2,127,127,127,127,127,127,127,  2, 79,  2,  2,  2,115,115,
-  115,115,115,115,115,  2,115,115,  2,  2,  2,  2,115,115,159,159,
-  159,159,159,159,159,  2,159,159,  2,  2,103,103,103,103,103,103,
-    2,  2,119,119,119,119,119,119,  2,  2,119,119,  2,119,  2,119,
-  119,119,146,146,146,146,146,146,146,  2, 99, 99, 99, 99, 99, 99,
-   99,  2,  2,  2,  2, 99,136,139, 13, 13,155,  2,  2,  2,136,136,
-  136,136,155,155,155,155,155,155,  2,  2,136,  2,  2,  2,  2, 17,
-   17, 17,  2, 17, 17,  2, 17, 15, 15, 15, 17, 17, 17,  2,  2,  2,
-   15,  2,  2, 17,  2,  2,139,139,139,139,105,105,105,105,105,105,
-  105,  2,105,  2,  2,  2,105,105,  2,  2,  1,  1,  2,  2,  0,  0,
-    0,  1,  0,  1,  1,  1,  0,  0,  1,  1,  2,  2,  0,  2,  2,  0,
-    0,  2,  0,  2,  0,  2,131,131,131,131,  2,  2,  2,131,  2,131,
-  131,131, 56, 56, 56,  2, 56,  2,  2, 56, 56, 56,  2, 56, 56,  2,
-   56, 56,  6,  6,  2,  2,  2,  2,  2,  6,151,151,151,151,151,  2,
-    2,  2,151,151,  2,  2,  2,  2,151,151,160,160,160,160,160,160,
-  160,  2,152,152,152,152,152,152,  2,  2,  2,  2,  2,152,164,164,
-  164,164,164,164,  2,  2,  2, 30, 30,  2,113,113,113,113,113,  2,
-    2,113,113,113,113,  2,132,132,132,132,132,132,  2,  2,  2,  2,
-  132,132,  2,  3,  3,  2,  3,  2,  2,  3,  2,  3,  2,  3,  2,  2,
-    3,  2,  3,  2,  3,  2,  3,  3,  2,  3, 15,  0,  0,  2, 13,  2,
-    2,  2, 13, 13, 13,  2,  2,  0,  2,  2,  0,  1,  2,  3,  4,  5,
-    6,  7,  8,  9,  9,  9,  9, 10,  9, 11, 12, 13,  9,  9,  9, 14,
-    9,  9, 15,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 70, 70,
+   70, 70,242, 96, 96, 96, 70, 70, 70, 70,243, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,244, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,245, 96, 96,
+   96, 96, 96, 96, 96, 96,246, 96,247,248,  0,  1,  2,  2,  0,  1,
+    2,  2,  2,  3,  4,  5,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  0,  0,  0, 19,  0, 19,  0,  0,  0,  0,  0,
+   26, 26,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
+    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
+    9,  2,  9,  2,  9,  9,  9,  9,  2,  9,  9,  9, 55, 55, 55, 55,
+   55, 55,  6,  6,  6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  2,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14,  2,  2,  2,  2, 14, 14,  2,  2,  2,  3,  3,  3,  3,  3,  0,
+    3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  1,  1,  1,
+    3,  3,  1,  3,  3,  3, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
+   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38,  2,  2, 64, 64,
+   64, 64, 64, 64, 64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90,
+    2,  2, 90, 90, 90,  2, 95, 95, 95, 95,  2,  2, 95,  2,  3,  3,
+    3,  2,  3,  3,  2,  2,  3,  3,  0,  3,  7,  7,  7,  7,  7,  1,
+    1,  1,  1,  7,  7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,
+    5,  5,  5,  2,  2,  5,  5,  2,  5,  5,  5,  2,  5,  2,  2,  2,
+    5,  5,  5,  5,  2,  2,  5,  5,  5,  2,  2,  2,  2,  5,  5,  5,
+    2,  5,  2, 11, 11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,
+    2, 11, 11, 11, 11, 11, 11,  2, 11, 11,  2, 11, 11,  2, 11, 11,
+    2,  2,  2, 11,  2,  2, 11,  2, 11,  2,  2,  2, 11, 11,  2, 10,
+   10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10,  2, 10, 10, 10, 10,
+    2,  2, 10,  2,  2,  2,  2,  2, 10, 10,  2, 21, 21, 21, 21, 21,
+   21, 21, 21,  2,  2, 21, 21,  2, 21, 21, 21, 21,  2,  2, 21, 21,
+    2, 21,  2,  2, 21, 21,  2,  2, 22, 22,  2, 22, 22, 22, 22, 22,
+   22,  2, 22,  2, 22, 22, 22, 22,  2,  2,  2, 22, 22,  2,  2,  2,
+    2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 23, 23, 23, 23, 23,  2,
+   23, 23, 23, 23,  2,  2,  2, 23, 23,  2, 23, 23, 23,  2,  2, 23,
+    2,  2,  2,  2, 23, 23,  2,  2,  2, 23, 16, 16, 16, 16, 16,  2,
+   16, 16,  2, 16, 16, 16, 16, 16,  2,  2,  2, 16, 16,  2,  2,  2,
+   16, 16, 20, 20, 20, 20, 20,  2, 20, 20,  2,  2, 20, 20,  2, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2, 36, 36, 36, 36,
+    2, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36,  2,
+   36,  2, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24,  2,  2,  2,  2,  0,  2, 18, 18,  2, 18,  2, 18, 18, 18, 18,
+   18,  2, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18,  2,  2, 18,  2,
+   18,  2, 25, 25, 25, 25,  2, 25, 25, 25, 25,  2,  2,  2, 25,  2,
+   25, 25, 25,  0,  0,  0,  0, 25, 25,  2, 33, 33, 33, 33,  8,  8,
+    8,  8,  8,  8,  2,  8,  2,  8,  2,  2,  8,  8,  8,  0, 12, 12,
+   12, 12, 30, 30, 30, 30, 30,  2, 30, 30, 30, 30,  2,  2, 30, 30,
+   30,  2,  2, 30, 30, 30, 30,  2,  2,  2, 29, 29, 29, 29, 29, 29,
+    2,  2, 28, 28, 28, 28, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
+   35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,  2,  2, 45, 45,
+   45, 45, 45, 45,  2,  2,  2,  2,  2, 45, 44, 44, 44, 44, 44,  0,
+    0,  2, 43, 43, 43, 43, 46, 46, 46, 46, 46,  2, 46, 46, 31, 31,
+   31, 31, 31, 31,  2,  2, 32, 32,  0,  0, 32,  0, 32, 32, 32, 32,
+   32, 32, 32, 32,  2,  2, 32,  2,  2,  2, 32, 32, 32,  2, 28, 28,
+    2,  2, 48, 48, 48, 48, 48, 48, 48,  2, 48,  2,  2,  2, 52, 52,
+   52, 52, 52, 52,  2,  2, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58,
+    2,  2, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54, 54, 54,  2,  2,
+   54, 54, 91, 91, 91, 91, 91, 91, 91,  2, 91,  2,  2, 91, 91, 91,
+    2,  2,  1,  1,  1,  2, 62, 62, 62, 62, 62,  2,  2,  2, 62, 62,
+   62,  2, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70,  2,  2,
+    2, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73, 73, 73,  6,  2,
+    2,  2,  8,  8,  8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  0,
+    1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  1,  1,  0,  2, 19, 19,
+    9,  9,  9,  9,  9,  6, 19,  9,  9,  9,  9,  9, 19, 19,  9,  9,
+    9, 19,  6, 19, 19, 19, 19, 19, 19,  9,  9,  9,  2,  2,  2,  9,
+    2,  9,  2,  9,  9,  9,  1,  1,  0,  0,  0,  2,  0,  0,  0, 19,
+    2,  2,  0,  0,  0, 19,  0,  0,  0,  2, 19,  2,  2,  2,  0,  2,
+    2,  2,  1,  2,  2,  2,  0,  0,  9,  0,  0,  0, 19, 19, 27, 27,
+   27, 27,  2,  2,  0,  0,  0,  0,  2,  0, 56, 56, 56, 56,  2, 55,
+   55, 55, 61, 61, 61, 61,  2,  2,  2, 61, 61,  2,  2,  2,  0,  0,
+    2,  2, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13,  2,  2,  0, 13,
+    0, 13,  0, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12,  2, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  1,  1,  0,  0, 15,
+   15, 15,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,  0,  2, 26,
+   26, 26, 26, 26, 26, 26,  2, 12, 12, 12, 12, 12, 12,  2, 12, 12,
+   12,  0, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39, 39,  2, 86, 86,
+   86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 19, 19, 19,  2, 19, 19,
+    2, 19,  2, 19, 19, 19, 19, 19,  2,  2,  2,  2, 19, 19, 60, 60,
+   60, 60, 60,  2,  2,  2, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75,
+    2,  2,  2,  2, 75, 75, 69, 69, 69, 69, 69, 69,  0, 69, 74, 74,
+   74, 74,  2,  2,  2, 74, 12,  2,  2,  2, 84, 84, 84, 84, 84, 84,
+    2,  0, 84, 84,  2,  2,  2,  2, 84, 84, 33, 33, 33,  2, 68, 68,
+   68, 68, 68, 68, 68,  2, 68, 68,  2,  2, 92, 92, 92, 92, 92, 92,
+   92,  2,  2,  2,  2, 92, 87, 87, 87, 87, 87, 87, 87,  2, 19,  9,
+   19, 19, 19, 19,  0,  0, 87, 87,  2,  2,  2,  2,  2, 12,  2,  2,
+    2,  4, 14,  2, 14,  2, 14, 14,  2, 14, 14,  2, 14, 14,  2,  2,
+    2,  3,  3,  3,  0,  0,  2,  2,  3,  3,  1,  1,  6,  6,  3,  2,
+    3,  3,  3,  2,  2,  0,  2,  0,  0,  0,  0,  0, 17, 17, 17, 17,
+    0,  0,  2,  2, 12, 12, 49, 49, 49, 49,  2, 49, 49, 49, 49, 49,
+   49,  2, 49, 49,  2, 49, 49, 49,  2,  2,  9,  2,  2,  2,  0,  1,
+    2,  2, 71, 71, 71, 71, 71,  2,  2,  2, 67, 67, 67, 67, 67,  2,
+    2,  2, 42, 42, 42, 42,  2, 42, 42, 42, 41, 41, 41, 41, 41, 41,
+   41,  2,118,118,118,118,118,118,118,  2, 53, 53, 53, 53, 53, 53,
+    2, 53, 59, 59, 59, 59, 59, 59,  2,  2, 40, 40, 40, 40, 51, 51,
+   51, 51, 50, 50, 50, 50, 50, 50,  2,  2,135,135,135,135,106,106,
+  106,106,104,104,104,104,  2,  2,  2,104,161,161,161,161,161,161,
+  161,  2,161,161,  2,161,161,  2,  2,  2,110,110,110,110,110,110,
+  110,  2,110,110,  2,  2, 19,  2, 19, 19, 47, 47, 47, 47, 47, 47,
+    2,  2, 47,  2, 47, 47, 47, 47,  2, 47, 47,  2,  2,  2, 47,  2,
+    2, 47, 81, 81, 81, 81, 81, 81,  2, 81,120,120,120,120,116,116,
+  116,116,116,116,116,  2,  2,  2,  2,116,128,128,128,128,128,128,
+  128,  2,128,128,  2,  2,  2,  2,  2,128, 66, 66, 66, 66,  2,  2,
+    2, 66, 72, 72, 72, 72, 72, 72,  2,  2,  2,  2,  2, 72, 98, 98,
+   98, 98, 97, 97, 97, 97,  2,  2, 97, 97, 57, 57, 57, 57,  2, 57,
+   57,  2,  2, 57, 57, 57, 57, 57,  2,  2, 57, 57, 57,  2,  2,  2,
+    2, 57, 57,  2,  2,  2, 88, 88, 88, 88,117,117,117,117,112,112,
+  112,112,112,112,112,  2,  2,  2,  2,112, 78, 78, 78, 78, 78, 78,
+    2,  2,  2, 78, 78, 78, 83, 83, 83, 83, 83, 83,  2,  2, 82, 82,
+   82, 82, 82, 82, 82,  2,122,122,122,122,122,122,  2,  2,  2,122,
+  122,122,122,  2,  2,  2, 89, 89, 89, 89, 89,  2,  2,  2,130,130,
+  130,130,130,130,130,  2,  2,  2,130,130,144,144,144,144,144,144,
+    2,  2,156,156,156,156,156,156,  2,156,156,156,  2,  2,  2,  3,
+    3,  3,147,147,147,147,148,148,148,148,148,148,  2,  2,158,158,
+  158,158,158,158,  2,  2,153,153,153,153,149,149,149,149,149,149,
+  149,  2, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2, 94, 94,  2,  2,
+    2, 94, 85, 85, 85, 85, 85, 85, 85,  2,  2, 85,  2,  2,101,101,
+  101,101,101,  2,  2,  2,101,101,  2,  2, 96, 96, 96, 96, 96,  2,
+   96, 96,111,111,111,111,111,111,111,  2,100,100,100,100,108,108,
+  108,108,108,108,  2,108,108,108,  2,  2,129,129,129,129,129,129,
+  129,  2,129,  2,129,129,129,129,  2,129,129,129,  2,  2,109,109,
+  109,109,109,109,109,  2,109,109,  2,  2,107,107,107,107,  2,107,
+  107,107,107,  2,  2,107,107,  2,107,107,107,107,  2,  1,107,107,
+    2,  2,107,  2,  2,  2,  2,  2,  2,107,  2,  2,107,107,137,137,
+  137,137,  2,137,137,137,137,137,  2,  2,124,124,124,124,124,124,
+    2,  2,123,123,123,123,123,123,  2,  2,114,114,114,114,114,  2,
+    2,  2,114,114,  2,  2,102,102,102,102,102,102,  2,  2,126,126,
+  126,126,126,126,126,  2,  2,126,126,126,142,142,142,142,125,125,
+  125,125,125,125,125,  2,  2,  2,  2,125,154,154,154,154,154,154,
+  154,  2,  2,154,  2,  2,  2,154,154,  2,154,154,  2,154,154,  2,
+    2,154,154,154,  2,  2,150,150,150,150,  2,  2,150,150,150,  2,
+    2,  2,141,141,141,141,140,140,140,140,140,140,140,  2,121,121,
+  121,121,121,  2,  2,  2,  7,  7,  2,  2,133,133,133,133,133,  2,
+  133,133,133,133,133,  2,133,133,  2,  2,133,  2,  2,  2,134,134,
+  134,134,  2,  2,134,134,  2,134,134,134,134,134,134,  2,138,138,
+  138,138,138,138,138,  2,138,138,  2,138,  2,  2,138,  2,138,138,
+    2,  2,143,143,143,143,143,143,  2,143,143,  2,143,143,143,143,
+  143,  2,143,  2,  2,  2,143,143,  2,  2,145,145,145,145,145,  2,
+    2,  2,163,163,163,163,163,  2,163,163,163,163,163,  2,  2,  2,
+  163,163,163,163,  2,  2, 86,  2,  2,  2, 63, 63, 63, 63, 63, 63,
+    2,  2, 63, 63, 63,  2, 63,  2,  2,  2,157,157,157,157,157,157,
+  157,  2, 80, 80, 80, 80, 80, 80,  2,  2,127,127,127,127,127,127,
+  127,  2, 79,  2,  2,  2,115,115,115,115,115,115,115,  2,115,115,
+    2,  2,  2,  2,115,115,159,159,159,159,159,159,159,  2,159,159,
+    2,  2,103,103,103,103,103,103,  2,  2,119,119,119,119,119,119,
+    2,  2,119,119,  2,119,  2,119,119,119,146,146,146,146,146,146,
+  146,  2, 99, 99, 99, 99, 99, 99, 99,  2,  2,  2,  2, 99,136,139,
+   13, 13,155,  2,  2,  2,136,136,136,136,155,155,155,155,155,155,
+    2,  2,136,  2,  2,  2,  2, 17, 17, 17,  2, 17, 17,  2, 17, 15,
+   15, 15, 17, 17, 17,  2,  2,  2, 15,  2,  2, 17,  2,  2,139,139,
+  139,139,105,105,105,105,105,105,105,  2,105,  2,  2,  2,105,105,
+    2,  2,  1,  1,  2,  2,  0,  0,  0,  1,  0,  1,  1,  1,  0,  0,
+    1,  1,  2,  2,  0,  2,  2,  0,  0,  2,  0,  2,  0,  2,131,131,
+  131,131,  2,  2,  2,131,  2,131,131,131, 56, 56, 56,  2, 56,  2,
+    2, 56, 56, 56,  2, 56, 56,  2, 56, 56,  6,  6,  2,  2,  2,  2,
+    2,  6,151,151,151,151,151,  2,  2,  2,151,151,  2,  2,  2,  2,
+  151,151,160,160,160,160,160,160,160,  2,152,152,152,152,152,152,
+    2,  2,  2,  2,  2,152,164,164,164,164,164,164,  2,  2,  2, 30,
+   30,  2,113,113,113,113,113,  2,  2,113,113,113,113,  2,132,132,
+  132,132,132,132,  2,  2,  2,  2,132,132,  2,  3,  3,  2,  3,  2,
+    2,  3,  2,  3,  2,  3,  2,  2,  3,  2,  3,  2,  3,  2,  3,  3,
+    2,  3, 15,  0,  0,  2, 13,  2,  2,  2, 13, 13, 13,  2,  2,  0,
+    2,  2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  9,  9,  9, 10,
+    9, 11, 12, 13,  9,  9,  9, 14,  9,  9, 15,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9, 16, 17,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9, 18, 19, 20,  9, 21,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 16, 17,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 18, 19, 20,  9, 21,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9, 22,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 22,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
@@ -3702,60 +3704,60 @@
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9, 23, 24,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
-    0,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0,  0, 24,
-   25, 26, 27, 28, 29, 30,  0,  0, 31, 32,  0, 33,  0, 34,  0, 35,
-    0,  0,  0,  0, 36, 37, 38, 39,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 40,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 41, 42,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 43, 44,  0, 45,  0,  0,
-    0,  0,  0,  0, 46, 47,  0,  0,  0,  0,  0, 48,  0, 49,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 50, 51,  0,  0,
-    0, 52,  0,  0, 53,  0,  0,  0,  0,  0,  0,  0, 54,  0,  0,  0,
-    0,  0,  0,  0, 55,  0,  0,  0,  0,  0,  0,  0, 56,  0,  0,  0,
-    0,  0,  0,  0,  0, 57,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 58, 59, 60, 61,
-   62, 63, 64, 65,  0,  0,  0,  0,  0,  0, 66,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 67, 68,  0, 69, 70,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 71, 72, 73, 74, 75, 76, 77, 78,
-   79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
-   95, 96, 97, 98, 99,100,101,102,103,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,104,  0,  0,  0,  0,  0,
-    0,105,106,  0,107,  0,  0,  0,108,  0,109,  0,110,  0,111,112,
-  113,  0,114,  0,  0,  0,115,  0,  0,  0,116,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,117,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,118,119,120,121,
-    0,122,123,124,125,126,  0,127,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,128,129,130,131,132,133,134,135,
-  136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,
-  152,153,154,155,156,157,  0,  0,  0,158,159,160,161,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,162,163,  0,  0,  0,  0,  0,  0,  0,164,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,165,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,166,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,167,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,168,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,169,170,  0,
-    0,  0,  0,171,172,  0,  0,  0,173,174,175,176,177,178,179,180,
-  181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,
-  197,198,199,200,201,202,203,204,205,206,  0,  0,  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,  2,  3,  4,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 23, 24,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  8,  9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18,
+   19, 20, 21, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0,
+   31, 32,  0, 33,  0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 40,  0,  0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 43, 44,  0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,
+    0,  0,  0, 48,  0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,
+    0,  0,  0,  0, 54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,
+    0,  0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,
+    0,  0, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   67, 68,  0, 69, 70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+   87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,
+  103,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,104,  0,  0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,
+  108,  0,109,  0,110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,
+    0,  0,116,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,117,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,118,119,120,121,  0,122,123,124,125,126,  0,127,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+  144,145,146,147,148,149,150,151,152,153,154,155,156,157,  0,  0,
+    0,158,159,160,161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,162,163,  0,  0,  0,  0,  0,
+    0,  0,164,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,165,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,166,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,167,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,168,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,169,170,  0,  0,  0,  0,171,172,  0,  0,  0,
+  173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,
+  189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,
+  205,206,  0,  0,  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,  2,  3,  4,
 };
 static const uint16_t
-_hb_ucd_u16[10040] =
+_hb_ucd_u16[10060] =
 {
      0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
     13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
@@ -3798,9 +3800,9 @@
    209, 306, 209, 209, 209, 209, 209, 209,   9,   9,   9,  11,  11,  11, 307, 308,
     13,  13,  13,  13,  13,  13, 309, 310,  11,  11, 311,  48,  48,  48, 312, 313,
     48, 314, 315, 315, 315, 315,  32,  32, 316, 317, 318, 319, 320, 321, 140, 140,
-   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
-   326, 327, 328, 329, 136,  48,  48,  48,  48, 330, 178,  48,  48,  48,  48, 331,
-   332,  48,  48, 136,  48,  48,  48,  48, 200, 333,  48,  48, 209, 209, 323,  48,
+   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209,
+   325, 326, 327, 328, 136,  48,  48,  48,  48, 329, 178,  48,  48,  48,  48, 330,
+   331,  48,  48, 136,  48,  48,  48,  48, 200, 332,  48,  48, 209, 209, 333,  48,
    209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
     48,  48,  48,  48, 209, 209, 209, 209,  48, 338,  48,  48,  48,  48,  48,  48,
    151, 209, 209, 209, 287,  48,  48, 229, 339,  48, 340, 140,  13,  13, 341, 342,
@@ -3871,143 +3873,144 @@
      9,   9, 607,  11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
    271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
    659,  48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
-   209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
-   670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
-   673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
-   209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
-   209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
-   679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
-   674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
+   209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324,
+   671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209,
+   674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677,
+   209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679,
+   209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209,
+   680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426,
+   675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192,
     48,  48,  48,  48,  48,  48, 140, 140,  48,  48,  48, 207,  48,  48,  48,  48,
     48, 204,  48,  48,  48,  48,  48,  48,  48,  48, 478,  48,  48,  48,  48,  48,
-    48,  48,  48,  48,  48,  48, 100, 140,  48, 204, 140, 140, 140, 140, 140, 140,
-    48,  48,  48,  48,  71,  48,  48,  48,  48,  48,  48, 140, 140, 140, 140, 140,
-   683, 140, 570, 570, 570, 570, 570, 570,  32,  32,  32,  32,  32,  32,  32,  32,
-    32,  32,  32,  32,  32,  32,  32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
-   391, 391, 391, 391, 391, 391, 391, 685,   0,   0,   0,   0,   1,   2,   1,   2,
-     0,   0,   3,   3,   4,   5,   4,   5,   4,   4,   4,   4,   4,   4,   4,   4,
-     4,   4,   4,   6,   0,   0,   7,   0,   8,   8,   8,   8,   8,   8,   8,   9,
-    10,  11,  12,  11,  11,  11,  13,  11,  14,  14,  14,  14,  14,  14,  14,  14,
-    15,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  16,  17,  18,  17,  17,
-    19,  20,  21,  21,  22,  21,  23,  24,  25,  26,  27,  27,  28,  29,  27,  30,
-    27,  27,  27,  27,  27,  31,  27,  27,  32,  33,  33,  33,  34,  27,  27,  27,
-    35,  35,  35,  36,  37,  37,  37,  38,  39,  39,  40,  41,  42,  43,  44,  27,
-    45,  46,  27,  27,  27,  27,  47,  27,  48,  48,  48,  48,  48,  49,  50,  48,
-    51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,
-    67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,
-    83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
-    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 109,
-   113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 122, 124, 125, 125,
-   126, 127, 128, 129, 130, 131, 125, 125, 132, 132, 132, 132, 133, 132, 134, 135,
-   132, 133, 132, 136, 136, 137, 125, 125, 138, 138, 138, 138, 138, 138, 138, 138,
-   138, 138, 139, 139, 140, 139, 139, 141, 142, 142, 142, 142, 142, 142, 142, 142,
-   143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143,
-   143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153,
-   154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159,
-   160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170,
-   171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176,
-   177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168,
-   188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194,   8, 195, 125, 125, 125,
-   196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201,
-   202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211,
-     4,   4, 212,   4,   4, 213, 214, 215,   4,   4,   4, 216,   8,   8,   8,   8,
-    11, 217,  11,  11, 217, 218,  11, 219,  11,  11,  11, 220, 220, 221,  11, 222,
-   223,   0,   0,   0,   0,   0, 224, 225, 226, 227,   0,   0, 228,   8,   8, 229,
-     0,   0, 230, 231, 232,   0,   4,   4, 233,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 234, 125, 235, 125,   0,   0,
-   236, 236, 236, 236, 236, 236, 236, 236,   0,   0,   0,   0,   0,   0,   0, 237,
-     0, 238,   0,   0,   0,   0,   0,   0, 239, 239, 239, 239, 239, 239,   4,   4,
-   240, 240, 240, 240, 240, 240, 240, 241, 139, 139, 140, 242, 242, 242, 243, 244,
-   143, 245, 246, 246, 246, 246,  14,  14,   0,   0,   0,   0,   0, 247, 125, 125,
-   248, 249, 248, 248, 248, 248, 248, 250, 248, 248, 248, 248, 248, 248, 248, 248,
-   248, 248, 248, 248, 248, 251, 125, 252, 253,   0, 254, 255, 256, 257, 257, 257,
-   257, 258, 259, 260, 260, 260, 260, 261, 262, 263, 263, 264, 142, 142, 142, 142,
-   265,   0, 263, 263,   0,   0, 266, 260, 142, 265,   0,   0,   0,   0, 142, 267,
-     0,   0,   0,   0,   0, 260, 260, 268, 260, 260, 260, 260, 260, 269,   0,   0,
-   248, 248, 248, 248,   0,   0,   0,   0, 270, 270, 270, 270, 270, 270, 270, 270,
-   271, 270, 270, 270, 272, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274,
-   274, 274, 275, 125,  14,  14,  14,  14,  14,  14, 276, 276, 276, 276, 276, 277,
-     0,   0, 278,   4,   4,   4,   4,   4, 279,   4,   4,   4, 280, 281, 125, 282,
-   283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290,  48,  48,
-   291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299,
-   300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308,
-   309, 310, 246,   4,   4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314,
-   142, 142, 315, 142, 316, 142, 142, 317, 125, 125, 125, 125, 125, 125, 125, 125,
-   248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125,
-   320, 321,  21, 322, 323,  27,  27,  27,  27,  27,  27,  27, 324, 325,  27,  27,
-    27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, 326,  27,  27,  27,  27,
-    27, 327,  27,  27, 328, 125, 125,  27,   8, 285, 329,   0,   0, 330, 331, 332,
-    27,  27,  27,  27,  27,  27,  27, 333, 334,   0,   1,   2,   1,   2, 335, 259,
-   260, 336, 142, 265, 337, 338, 339, 340, 341, 342, 343, 344, 345, 345, 125, 125,
-   342, 342, 342, 342, 342, 342, 342, 346, 347,   0,   0, 348,  11,  11,  11,  11,
-   349, 350, 351, 125, 125,   0,   0, 352, 353, 354, 355, 355, 355, 356, 357, 252,
-   358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125,
-   369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376,
-   377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125,
-   385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 387, 388, 125,
-   389,   4,   4, 390, 125, 125, 125, 125, 391, 392, 392, 393, 394, 395, 396, 396,
-   397, 398, 399, 125, 125, 125, 400, 401, 402, 403, 404, 405, 125, 125, 125, 125,
-   406, 406, 407, 408, 407, 409, 407, 407, 410, 411, 412, 413, 414, 414, 415, 415,
-   416, 416, 125, 125, 417, 417, 418, 419, 420, 420, 420, 421, 422, 423, 424, 425,
-   426, 427, 428, 125, 125, 125, 125, 125, 429, 429, 429, 429, 430, 125, 125, 125,
-   431, 431, 431, 432, 431, 431, 431, 433, 434, 434, 435, 436, 125, 125, 125, 125,
-   125, 125, 125, 125, 125, 125,  27,  45, 437, 437, 438, 439, 125, 125, 125, 440,
-   441, 441, 442, 443, 443, 444, 125, 445, 446, 125, 125, 447, 448, 125, 449, 450,
-   451, 451, 451, 451, 452, 453, 451, 454, 455, 455, 455, 455, 456, 457, 458, 459,
-   460, 460, 460, 461, 462, 463, 463, 464, 465, 465, 465, 465, 465, 465, 466, 467,
-   468, 469, 468, 468, 470, 125, 125, 125, 471, 472, 473, 474, 474, 474, 475, 476,
-   477, 478, 479, 480, 481, 482, 483, 484, 485, 485, 485, 485, 485, 486, 487, 125,
-   488, 488, 488, 488, 489, 490, 125, 125, 491, 491, 491, 492, 491, 493, 125, 125,
-   494, 494, 494, 494, 495, 496, 497, 125, 498, 498, 498, 499, 499, 125, 125, 125,
-   500, 501, 502, 500, 503, 125, 125, 125, 504, 504, 504, 505, 125, 125, 125, 125,
-   125, 125, 506, 506, 506, 506, 506, 507, 508, 509, 510, 511, 512, 513, 125, 125,
-   125, 125, 514, 515, 515, 514, 516, 125, 517, 517, 517, 517, 518, 519, 519, 519,
-   519, 519, 520, 154, 521, 521, 521, 522, 523, 125, 125, 125, 125, 125, 125, 125,
-   524, 525, 525, 526, 527, 525, 528, 529, 529, 530, 531, 532, 125, 125, 125, 125,
-   533, 534, 534, 535, 536, 537, 538, 539, 540, 541, 542, 125, 125, 125, 125, 125,
-   125, 125, 125, 125, 125, 125, 543, 544, 545, 546, 545, 547, 545, 548, 125, 125,
-   125, 125, 125, 549, 550, 550, 550, 551, 552, 552, 552, 552, 552, 552, 552, 552,
-   552, 553, 125, 125, 125, 125, 125, 125, 552, 552, 552, 552, 552, 552, 554, 555,
-   552, 552, 552, 552, 556, 125, 125, 125, 125, 557, 557, 557, 557, 557, 557, 558,
-   559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 560, 125, 125,
-   561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, 125, 125, 125,
-   276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 563, 564, 565, 566, 567,
-   567, 567, 567, 568, 569, 570, 571, 572, 573, 573, 573, 573, 574, 575, 576, 577,
-   573, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 578, 578, 578, 578,
-   578, 579, 125, 125, 125, 125, 125, 125, 580, 580, 580, 580, 581, 580, 580, 580,
-   582, 580, 125, 125, 125, 125, 583, 584, 585, 585, 585, 585, 585, 585, 585, 585,
-   585, 585, 585, 585, 585, 585, 585, 586, 587, 587, 587, 587, 587, 587, 587, 587,
-   587, 587, 587, 587, 587, 588, 125, 125, 589, 125, 125, 125, 125, 125, 125, 125,
-   125, 125, 125, 125, 125, 125, 125, 590, 591, 257, 257, 257, 257, 257, 257, 257,
-   257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 592, 593, 125, 594, 595, 596,
-   596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597,
-   598, 598, 598, 598, 598, 598, 599, 600, 601, 602, 266, 125, 125, 125, 125, 125,
-     8,   8, 603,   8, 604,   0,   0,   0,   0,   0,   0,   0, 266, 125, 125, 125,
-     0,   0,   0,   0,   0,   0,   0, 605,   0,   0, 606,   0,   0,   0, 607, 608,
-   609,   0, 610,   0,   0,   0, 235, 125,  11,  11,  11,  11, 611, 125, 125, 125,
-   125, 125, 125, 125,   0, 266,   0, 266,   0,   0,   0,   0,   0, 234,   0, 612,
-     0,   0,   0,   0,   0, 224,   0,   0,   0, 613, 614, 615, 616,   0,   0,   0,
-   617, 618,   0, 619, 620, 621,   0,   0,   0,   0, 622,   0,   0,   0,   0,   0,
-     0,   0,   0,   0, 623,   0,   0,   0, 624, 624, 624, 624, 624, 624, 624, 624,
-   625, 626, 627, 125, 125, 125, 125, 125,   4, 628, 629, 125, 125, 125, 125, 125,
-   630, 631, 632,  14,  14,  14, 633, 125, 634, 125, 125, 125, 125, 125, 125, 125,
-   635, 635, 636, 637, 638, 125, 125, 125, 125, 639, 640, 125, 641, 641, 641, 642,
-   125, 125, 125, 125, 125, 643, 643, 644, 125, 125, 125, 125, 125, 125, 645, 646,
-   647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 648, 649, 125, 125,
-   650, 650, 650, 650, 651, 652, 125, 125, 125, 125, 125, 125, 125, 125, 125, 334,
-     0,   0,   0, 653, 125, 125, 125, 125, 334,   0,   0, 247, 125, 125, 125, 125,
-   654,  27, 655, 656, 657, 658, 659, 660, 661, 662, 663, 662, 125, 125, 125, 664,
-     0,   0, 252,   0,   0,   0,   0,   0,   0, 266, 226, 334, 334, 334,   0, 605,
-     0,   0, 247, 125, 125, 125, 665,   0, 666,   0,   0, 252, 612, 667, 605, 125,
-     0,   0,   0,   0,   0, 668, 350, 350,   0,   0,   0,   0,   0,   0,   0, 669,
-     0,   0,   0,   0,   0, 285, 252, 228, 252,   0,   0,   0, 670, 285,   0,   0,
-   670,   0, 247, 667, 125, 125, 125, 125,   0,   0,   0,   0,   0, 266, 247, 350,
-   612,   0,   0, 671, 672, 252, 612, 612,   0, 330,   0,   0, 235, 125, 125, 285,
-   248, 248, 248, 248, 248, 248, 125, 125, 248, 248, 248, 319, 248, 248, 248, 248,
-   248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 584, 248, 248, 248, 248, 248,
-   248, 248, 248, 248, 248, 248, 673, 125, 248, 318, 125, 125, 125, 125, 125, 125,
-   248, 248, 248, 248, 674, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125,
-   675, 125,   0,   0,   0,   0,   0,   0,   8,   8,   8,   8,   8,   8,   8,   8,
+    48,  48,  48,  48,  48,  48, 100,  48,  48,  48,  48,  48,  48, 204, 140, 140,
+    48, 204, 140, 140, 140, 140, 140, 140,  48,  48,  48,  48,  71,  48,  48,  48,
+    48,  48,  48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 140,
+   391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686,
+     0,   0,   0,   0,   1,   2,   1,   2,   0,   0,   3,   3,   4,   5,   4,   5,
+     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   6,   0,   0,   7,   0,
+     8,   8,   8,   8,   8,   8,   8,   9,  10,  11,  12,  11,  11,  11,  13,  11,
+    14,  14,  14,  14,  14,  14,  14,  14,  15,  14,  14,  14,  14,  14,  14,  14,
+    14,  14,  14,  16,  17,  18,  17,  17,  19,  20,  21,  21,  22,  21,  23,  24,
+    25,  26,  27,  27,  28,  29,  27,  30,  27,  27,  27,  27,  27,  31,  27,  27,
+    32,  33,  33,  33,  34,  27,  27,  27,  35,  35,  35,  36,  37,  37,  37,  38,
+    39,  39,  40,  41,  42,  43,  44,  27,  45,  46,  27,  27,  27,  27,  47,  27,
+    48,  48,  48,  48,  48,  49,  50,  48,  51,  52,  53,  54,  55,  56,  57,  58,
+    59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
+    75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,
+    91,  92,  93,  94,  95,  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106,
+   107, 108, 109, 109, 110, 111, 112, 109, 113, 114, 115, 116, 117, 118, 119, 120,
+   121, 122, 122, 123, 122, 124, 125, 125, 126, 127, 128, 129, 130, 131, 125, 125,
+   132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 125, 125,
+   138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141,
+   142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 144, 145, 143, 143,
+   144, 143, 143, 146, 147, 148, 143, 143, 143, 147, 143, 143, 143, 149, 143, 150,
+   143, 151, 152, 152, 152, 152, 152, 153, 154, 154, 154, 154, 154, 154, 154, 154,
+   155, 156, 157, 157, 157, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
+   168, 168, 168, 168, 168, 169, 170, 170, 171, 172, 173, 173, 173, 173, 173, 174,
+   173, 173, 175, 154, 154, 154, 154, 176, 177, 178, 179, 179, 180, 181, 182, 183,
+   184, 184, 185, 184, 186, 187, 168, 168, 188, 189, 190, 190, 190, 191, 190, 192,
+   193, 193, 194,   8, 195, 125, 125, 125, 196, 196, 196, 196, 197, 196, 196, 198,
+   199, 199, 199, 199, 200, 200, 200, 201, 202, 202, 202, 203, 204, 205, 205, 205,
+   206, 139, 139, 207, 208, 209, 210, 211,   4,   4, 212,   4,   4, 213, 214, 215,
+     4,   4,   4, 216,   8,   8,   8,   8,  11, 217,  11,  11, 217, 218,  11, 219,
+    11,  11,  11, 220, 220, 221,  11, 222, 223,   0,   0,   0,   0,   0, 224, 225,
+   226, 227,   0,   0, 228,   8,   8, 229,   0,   0, 230, 231, 232,   0,   4,   4,
+   233,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0, 234, 125, 235, 125,   0,   0, 236, 236, 236, 236, 236, 236, 236, 236,
+     0,   0,   0,   0,   0,   0,   0, 237,   0, 238,   0,   0,   0,   0,   0,   0,
+   239, 239, 239, 239, 239, 239,   4,   4, 240, 240, 240, 240, 240, 240, 240, 241,
+   139, 139, 140, 242, 242, 242, 243, 244, 143, 245, 246, 246, 246, 246,  14,  14,
+     0,   0,   0,   0,   0, 247, 125, 125, 248, 249, 248, 248, 248, 248, 248, 250,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 125,   0,
+   252,   0, 253, 254, 255, 256, 256, 256, 256, 257, 258, 259, 259, 259, 259, 260,
+   261, 262, 262, 263, 142, 142, 142, 142, 264,   0, 262, 262,   0,   0, 265, 259,
+   142, 264,   0,   0,   0,   0, 142, 266,   0,   0,   0,   0,   0, 259, 259, 267,
+   259, 259, 259, 259, 259, 268,   0,   0, 248, 248, 248, 248,   0,   0,   0,   0,
+   269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269, 271, 272, 272, 272,
+   273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 125,  14,  14,  14,  14,
+    14,  14, 275, 275, 275, 275, 275, 276,   0,   0, 277,   4,   4,   4,   4,   4,
+   278,   4,   4,   4, 279, 280, 125, 281, 282, 282, 283, 284, 285, 285, 285, 286,
+   287, 287, 287, 287, 288, 289,  48,  48, 290, 290, 291, 292, 292, 293, 142, 294,
+   295, 295, 295, 295, 296, 297, 138, 298, 299, 299, 299, 300, 301, 302, 138, 138,
+   303, 303, 303, 303, 304, 305, 306, 307, 308, 309, 246,   4,   4, 310, 311, 152,
+   152, 152, 152, 152, 306, 306, 312, 313, 142, 142, 314, 142, 315, 142, 142, 316,
+   125, 125, 125, 125, 125, 125, 125, 125, 248, 248, 248, 248, 248, 248, 317, 248,
+   248, 248, 248, 248, 248, 318, 125, 125, 319, 320,  21, 321, 322,  27,  27,  27,
+    27,  27,  27,  27, 323, 324,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,
+    27,  27,  27, 325,  27,  27,  27,  27,  27, 326,  27,  27, 327, 125, 125,  27,
+     8, 284, 328,   0,   0, 329, 330, 331,  27,  27,  27,  27,  27,  27,  27, 332,
+   333,   0,   1,   2,   1,   2, 334, 258, 259, 335, 142, 264, 336, 337, 338, 339,
+   340, 341, 342, 343, 344, 344, 125, 125, 341, 341, 341, 341, 341, 341, 341, 345,
+   346,   0,   0, 347,  11,  11,  11,  11, 348, 349, 350, 125, 125,   0,   0, 351,
+   352, 353, 354, 354, 354, 355, 356, 357, 358, 358, 359, 360, 361, 362, 362, 363,
+   364, 365, 366, 366, 367, 368, 125, 125, 369, 369, 369, 369, 369, 370, 370, 370,
+   371, 372, 373, 374, 374, 375, 374, 376, 377, 377, 378, 379, 379, 379, 380, 381,
+   381, 382, 383, 384, 125, 125, 125, 125, 385, 385, 385, 385, 385, 385, 385, 385,
+   385, 385, 385, 386, 385, 387, 388, 125, 389,   4,   4, 390, 125, 125, 125, 125,
+   391, 392, 392, 393, 394, 395, 396, 396, 397, 398, 399, 125, 125, 125, 400, 401,
+   402, 403, 404, 405, 125, 125, 125, 125, 406, 406, 407, 408, 407, 409, 407, 407,
+   410, 411, 412, 413, 414, 414, 415, 415, 416, 416, 125, 125, 417, 417, 418, 419,
+   420, 420, 420, 421, 422, 423, 424, 425, 426, 427, 428, 125, 125, 125, 125, 125,
+   429, 429, 429, 429, 430, 125, 125, 125, 431, 431, 431, 432, 431, 431, 431, 433,
+   434, 434, 435, 436, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,  27,  45,
+   437, 437, 438, 439, 125, 125, 125, 440, 441, 441, 442, 443, 443, 444, 125, 445,
+   446, 125, 125, 447, 448, 125, 449, 450, 451, 451, 451, 451, 452, 453, 451, 454,
+   455, 455, 455, 455, 456, 457, 458, 459, 460, 460, 460, 461, 462, 463, 463, 464,
+   465, 465, 465, 465, 465, 465, 466, 467, 468, 469, 468, 468, 470, 125, 125, 125,
+   471, 472, 473, 474, 474, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484,
+   485, 485, 485, 485, 485, 486, 487, 125, 488, 488, 488, 488, 489, 490, 125, 125,
+   491, 491, 491, 492, 491, 493, 125, 125, 494, 494, 494, 494, 495, 496, 497, 125,
+   498, 498, 498, 499, 499, 125, 125, 125, 500, 501, 502, 500, 503, 125, 125, 125,
+   504, 504, 504, 505, 125, 125, 125, 125, 125, 125, 506, 506, 506, 506, 506, 507,
+   508, 509, 510, 511, 512, 513, 125, 125, 125, 125, 514, 515, 515, 514, 516, 125,
+   517, 517, 517, 517, 518, 519, 519, 519, 519, 519, 520, 154, 521, 521, 521, 522,
+   523, 125, 125, 125, 125, 125, 125, 125, 524, 525, 525, 526, 527, 525, 528, 529,
+   529, 530, 531, 532, 125, 125, 125, 125, 533, 534, 534, 535, 536, 537, 538, 539,
+   540, 541, 542, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 543, 544,
+   545, 546, 545, 547, 545, 548, 125, 125, 125, 125, 125, 549, 550, 550, 550, 551,
+   552, 552, 552, 552, 552, 552, 552, 552, 552, 553, 125, 125, 125, 125, 125, 125,
+   552, 552, 552, 552, 552, 552, 554, 555, 552, 552, 552, 552, 556, 125, 125, 125,
+   125, 557, 557, 557, 557, 557, 557, 558, 559, 559, 559, 559, 559, 559, 559, 559,
+   559, 559, 559, 559, 559, 560, 125, 125, 561, 561, 561, 561, 561, 561, 561, 561,
+   561, 561, 561, 561, 562, 125, 125, 125, 275, 275, 275, 275, 275, 275, 275, 275,
+   275, 275, 275, 563, 564, 565, 566, 567, 567, 567, 567, 568, 569, 570, 571, 572,
+   573, 573, 573, 573, 574, 575, 576, 577, 573, 125, 125, 125, 125, 125, 125, 125,
+   125, 125, 125, 125, 578, 578, 578, 578, 578, 579, 125, 125, 125, 125, 125, 125,
+   580, 580, 580, 580, 581, 580, 580, 580, 582, 580, 125, 125, 125, 125, 583, 584,
+   585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 586,
+   587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 125, 125,
+   589, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 590,
+   591, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+   256, 256, 592, 593, 125, 594, 595, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+   596, 596, 596, 596, 596, 596, 596, 597, 598, 598, 598, 598, 598, 598, 599, 600,
+   601, 602, 603, 125, 125, 125, 125, 125,   8,   8, 604,   8, 605,   0,   0,   0,
+     0,   0,   0,   0, 603, 125, 125, 125,   0,   0,   0,   0,   0,   0,   0, 606,
+     0,   0, 607,   0,   0,   0, 608, 609, 610,   0, 611,   0,   0,   0, 235, 125,
+    11,  11,  11,  11, 612, 125, 125, 125, 125, 125, 125, 125,   0, 603,   0, 603,
+     0,   0,   0,   0,   0, 234,   0, 613,   0,   0,   0,   0,   0, 224,   0,   0,
+     0, 614, 615, 616, 617,   0,   0,   0, 618, 619,   0, 620, 621, 622,   0,   0,
+     0,   0, 623,   0,   0,   0,   0,   0,   0,   0,   0,   0, 624,   0,   0,   0,
+   625, 625, 625, 625, 625, 625, 625, 625, 626, 627, 628, 125, 125, 125, 125, 125,
+     4, 629, 630, 125, 125, 125, 125, 125, 631, 632, 633,  14,  14,  14, 634, 125,
+   635, 125, 125, 125, 125, 125, 125, 125, 636, 636, 637, 638, 639, 125, 125, 125,
+   125, 640, 641, 125, 642, 642, 642, 643, 125, 125, 125, 125, 125, 644, 644, 645,
+   125, 125, 125, 125, 125, 125, 646, 647, 648, 648, 648, 648, 648, 648, 648, 648,
+   648, 648, 648, 648, 649, 650, 125, 125, 651, 651, 651, 651, 652, 653, 125, 125,
+   125, 125, 125, 125, 125, 125, 125, 333,   0,   0,   0, 654, 125, 125, 125, 125,
+   333,   0,   0, 247, 125, 125, 125, 125, 655,  27, 656, 657, 658, 659, 660, 661,
+   662, 663, 664, 663, 125, 125, 125, 665,   0,   0, 357,   0,   0,   0,   0,   0,
+     0, 603, 226, 333, 333, 333,   0, 606,   0,   0, 247, 125, 125, 125, 666,   0,
+   667,   0,   0, 357, 613, 668, 606, 125,   0,   0,   0,   0,   0, 669, 349, 349,
+     0,   0,   0,   0,   0,   0,   0, 670,   0,   0,   0,   0,   0, 284, 357, 228,
+   357,   0,   0,   0, 671, 284,   0,   0, 671,   0, 247, 668, 125, 125, 125, 125,
+     0,   0,   0,   0,   0, 603, 247, 349, 613,   0,   0, 672, 673, 357, 613, 613,
+     0, 329,   0,   0, 235, 125, 125, 284, 248, 248, 248, 248, 248, 248, 125, 125,
+   248, 248, 248, 318, 248, 248, 248, 248, 248, 317, 248, 248, 248, 248, 248, 248,
+   248, 248, 584, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 674, 248,
+   248, 248, 248, 248, 248, 317, 125, 125, 248, 317, 125, 125, 125, 125, 125, 125,
+   248, 248, 248, 248, 675, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125,
+   676, 125,   0,   0,   0,   0,   0,   0,   8,   8,   8,   8,   8,   8,   8,   8,
      8,   8,   8,   8,   8,   8,   8,   0,   0,   0,   0,   0,   1,   2,   2,   2,
      2,   2,   3,   0,   0,   0,   4,   0,   2,   2,   2,   2,   2,   3,   2,   2,
      2,   2,   5,   0,   2,   5,   6,   0,   7,   7,   7,   7,   8,   9,  10,  11,
@@ -4071,33 +4074,33 @@
      0, 240,   0,   0, 241, 241, 241, 241,  18,  18,  18,  18,  18,  12, 242,  18,
    243, 243, 243, 243, 243, 243,  12, 244, 245,  12,  12, 244, 151, 154,  12,  12,
    151, 154, 151, 154,   0,   0,   0, 246, 247, 247, 247, 247, 247, 247, 248, 247,
-   247,  12,  12,  12, 247, 249,  12,  12,   0,   0,   0,  12,   0, 250,   0,   0,
-   251, 247, 252, 253,   0,   0, 247,   0, 254, 255, 255, 255, 255, 255, 255, 255,
-   255, 256, 257, 258, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259,
-    12, 262, 263, 263, 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265,
-     0,  12,  12,  12, 150, 150, 150, 266, 260, 260, 260, 261, 260, 260,   0,   0,
-   267, 267, 267, 267, 267, 267, 267, 268, 267, 269,  12,  12, 270, 270, 270, 270,
-   271, 271, 271, 271, 271, 271, 271,  12, 272, 272, 272, 272, 272, 272,  12,  12,
-   237,   2,   2,   2,   2,   2, 231,   2,   2,   2, 273,  12, 274, 275, 276,  12,
-   277,   2,   2,   2, 278, 278, 278, 278, 278, 278, 278, 279,   0,   0, 246,  12,
-   280, 280, 280, 280, 280, 280,  12,  12, 281, 281, 281, 281, 281, 282,  12, 283,
-   281, 281, 282,  12, 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286,
-   286,  12,  12, 287, 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290,
-   289, 289, 291, 292, 145, 145, 145, 293, 294, 294, 294, 294, 294, 295,  12,  12,
-   294, 294, 294, 296, 294, 294, 296, 294, 297, 297, 297, 297, 298,  12,  12,  12,
-    12,  12, 299, 297, 300, 300, 300, 300, 300, 301,  12,  12, 155, 154, 155, 154,
-   155, 154,  12,  12,   2,   2,   3,   2,   2, 302, 303,  12, 300, 300, 300, 304,
-   300, 300, 304,  12, 150,  12,  12,  12, 150, 265, 305, 150, 150, 150, 150,  12,
-   247, 247, 247, 249, 247, 247, 249,  12,   2, 273,  12,  12, 306,  22,  12,  24,
-    25,  26,  25, 307, 308, 309,  25,  25,  50,  12,  12,  12, 310,  29,  29,  29,
-    29,  29,  29, 311, 312,  29,  29,  29,  29,  29,  12, 310,   7,   7,   7, 313,
-   232,   0,   0,   0,   0, 232,   0,  12,  29, 314,  29,  29,  29,  29,  29, 315,
-   316,   0,   0,   0,   0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150,
-   319, 150, 319, 288,   0, 232,   0, 232,  12,  12, 316, 246, 320, 320, 320, 321,
-   320, 320, 320, 320, 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324,
-   320, 320, 322,  12, 232, 131,   0,   0,   0, 131,   0,   0,   8,   8,   8,  14,
-     0,   0,   0, 234, 325,  12,  12,  12,   0,   0,   0, 326, 327, 327, 327, 327,
-   327, 327, 327, 328, 329, 329, 329, 329, 330,  12,  12,  12, 215,   0,   0,   0,
+   247,  12,  12,  12, 247, 249,  12,  12,   0, 250,   0,   0, 251, 247, 252, 253,
+     0,   0, 247,   0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 256, 257, 258,
+   259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259,  12, 262, 263, 263,
+   263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265,   0,  12,  12, 131,
+   150, 150, 150, 266, 260, 260, 260, 261, 260, 260,   0,   0, 267, 267, 267, 267,
+   267, 267, 267, 268, 267, 269,  12,  12, 270, 270, 270, 270, 271, 271, 271, 271,
+   271, 271, 271,  12, 272, 272, 272, 272, 272, 272,  12,  12, 237,   2,   2,   2,
+     2,   2, 231,   2,   2,   2, 273,  12, 274, 275, 276,  12, 277,   2,   2,   2,
+   278, 278, 278, 278, 278, 278, 278, 279,   0,   0, 246,  12, 280, 280, 280, 280,
+   280, 280,  12,  12, 281, 281, 281, 281, 281, 282,  12, 283, 281, 281, 282,  12,
+   284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286, 286,  12,  12, 287,
+   150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290, 289, 289, 291, 292,
+   145, 145, 145, 293, 294, 294, 294, 294, 294, 295,  12,  12, 294, 294, 294, 296,
+   294, 294, 296, 294, 297, 297, 297, 297, 298,  12,  12,  12,  12,  12, 299, 297,
+   300, 300, 300, 300, 300, 301,  12,  12, 155, 154, 155, 154, 155, 154,  12,  12,
+     2,   2,   3,   2,   2, 302, 303,  12, 300, 300, 300, 304, 300, 300, 304,  12,
+   150,  12,  12,  12, 150, 265, 305, 150, 150, 150, 150,  12, 247, 247, 247, 249,
+   247, 247, 249,  12,   2, 273,  12,  12, 306,  22,  12,  24,  25,  26,  25, 307,
+   308, 309,  25,  25,  50,  12,  12,  12, 310,  29,  29,  29,  29,  29,  29, 311,
+   312,  29,  29,  29,  29,  29,  12, 310,   7,   7,   7, 313, 232,   0,   0,   0,
+     0, 232,   0,  12,  29, 314,  29,  29,  29,  29,  29, 315, 316,   0,   0,   0,
+     0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150, 319, 150, 319, 288,
+     0, 232,   0, 232,  12,  12, 316, 246, 320, 320, 320, 321, 320, 320, 320, 320,
+   320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324, 320, 320, 322,  12,
+   232, 131,   0,   0,   0, 131,   0,   0,   8,   8,   8,  14,   0,   0,   0, 234,
+   325,  12,  12,  12,   0,   0,   0, 326, 327, 327, 327, 327, 327, 327, 327, 328,
+   329, 329, 329, 329, 330,  12,  12,  12, 215,   0,   0,   0,   0,   0,   0,  12,
    331, 331, 331, 331, 331,  12,  12, 332, 333, 333, 333, 333, 333, 333, 334,  12,
    335, 335, 335, 335, 335, 335, 336,  12, 337, 337, 337, 337, 337, 337, 337, 338,
    339, 339, 339, 339, 339,  12, 339, 339, 339, 340,  12,  12, 341, 341, 341, 341,
@@ -4159,232 +4162,232 @@
    260, 556, 260, 557, 558, 255, 255, 255, 559,  12,  12,  12, 560,  12,  12,  12,
    256, 561,  12,  12,  12, 260,  12,  12, 562, 562, 562, 562, 562, 562, 562,  12,
    563, 563, 563, 563, 563, 563, 564,  12, 563, 563, 563, 565, 563, 563, 565,  12,
-   563, 563, 566, 563,   7,   7,   7, 567,   7, 199,  12,  12,   0, 246,  12,  12,
-     0, 232, 316,   0,   0, 568, 228,   0,   0,   0, 568,   7, 213, 569,   7,   0,
-     0,   0, 570, 228,   8, 225,  12,  12,   0,   0, 234,  12,   0,   0,   0, 229,
-   571, 572, 316, 229,   0,   0, 240, 316,   0, 316,   0,   0,   0, 240, 232, 316,
-     0, 229,   0, 229,   0,   0, 240, 232,   0, 573, 239,   0, 229,   0,   0,   0,
-     0, 246,   0,   0,   0,   0,   0, 239, 574, 574, 574, 574, 574, 574, 574,  12,
-    12,  12, 575, 574, 576, 574, 574, 574,   2,   2,   2, 273,  12, 275, 273,  12,
-   241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577,  12,  19,  19,  19, 581,
-    12,  12,  12, 582, 583, 583, 583, 583, 583, 583, 583, 584, 583, 583, 583, 585,
-   583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, 589, 589, 589, 589,
-   589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593,  12, 151, 154, 151, 594,
-   151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, 595, 597,  12,  12,
-   598, 598, 598, 598, 598, 598, 598,  12, 598, 598, 599, 600,   0, 234,  12,  12,
-    29, 414,  29,  29, 601, 602, 414,  29,  50,  29, 603,  12, 604, 310, 603, 414,
-   601, 602, 603, 603, 601, 602,  50,  29,  50,  29, 414, 605,  29,  29, 606,  29,
-    29,  29,  29,  12, 414, 414, 606,  29,  51,  12,  12,  12,  12, 239,   0,   0,
-   607,  12,  12,  12, 246,  12,  12,  12,   0,   0,  12,   0,   0, 232, 131,   0,
-     0,   0,  12,  12,   0,   0,   0, 240,   0, 246,  12, 239, 608,  12,  12,  12,
-   247, 247, 609,  12, 610,  12,  12,  12,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 939, 940, 941, 942, 946, 948,   0, 962,
-   969, 970, 971, 976,1001,1002,1003,1008,   0,1033,1040,1041,1042,1043,1047,   0,
-     0,1080,1081,1082,1086,1110,   0,   0,1124,1125,1126,1127,1131,1133,   0,1147,
-  1154,1155,1156,1161,1187,1188,1189,1193,   0,1219,1226,1227,1228,1229,1233,   0,
-     0,1267,1268,1269,1273,1298,   0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
-   959,1144, 960,1145, 961,1146, 964,1149,   0,   0, 973,1158, 974,1159, 975,1160,
-   983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179,   0,   0,
-  1004,1190,1005,1191,1006,1192,1014,1199,1007,   0,   0,   0,1016,1201,1020,1206,
-     0,1022,1208,1025,1211,1023,1209,   0,   0,   0,   0,1032,1218,1037,1223,1035,
-  1221,   0,   0,   0,1044,1230,1045,1231,1049,1235,   0,   0,1058,1244,1064,1250,
-  1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261,   0,   0,
-  1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
-  1115,1118,1307,1120,1309,1121,1310,   0,1053,1239,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,1093,1280,   0,   0,   0,   0,   0,   0,   0,
+   563, 563, 566, 563,   0,  12,  12,  12,   7,   7,   7, 567,   7, 199,  12,  12,
+     0, 246,  12,  12,   0, 232, 316,   0,   0, 568, 228,   0,   0,   0, 568,   7,
+   213, 569,   7,   0,   0,   0, 570, 228,   8, 225,  12,  12,   0,   0, 234,  12,
+     0,   0,   0, 229, 571, 572, 316, 229,   0,   0, 240, 316,   0, 316,   0,   0,
+     0, 240, 232, 316,   0, 229,   0, 229,   0,   0, 240, 232,   0, 573, 239,   0,
+   229,   0,   0,   0,   0, 246,   0,   0,   0,   0,   0, 239, 574, 574, 574, 574,
+   574, 574, 574,  12,  12,  12, 575, 574, 576, 574, 574, 574,   2,   2,   2, 273,
+    12, 275, 273,  12, 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577,  12,
+    19,  19,  19, 581,  12,  12,  12, 582, 583, 583, 583, 583, 583, 583, 583, 584,
+   583, 583, 583, 585, 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588,
+   589, 589, 589, 589, 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593,  12,
+   151, 154, 151, 594, 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595,
+   595, 597,  12,  12, 598, 598, 598, 598, 598, 598, 598,  12, 598, 598, 599, 600,
+     0, 234,  12,  12,  29, 414,  29,  29, 601, 602, 414,  29,  50,  29, 603,  12,
+   604, 310, 603, 414, 601, 602, 603, 603, 601, 602,  50,  29,  50,  29, 414, 605,
+    29,  29, 606,  29,  29,  29,  29,  12, 414, 414, 606,  29,  51,  12,  12,  12,
+    12, 239,   0,   0, 607,  12,  12,  12, 246,  12,  12,  12,   0,   0,  12,   0,
+     0, 232, 131,   0,   0,   0,  12,  12,   0,   0,   0, 240,   0, 246,  12, 239,
+   608,  12,  12,  12, 247, 247, 609,  12, 610,  12,  12,  12,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 939, 940, 941, 942,
+   946, 948,   0, 962, 969, 970, 971, 976,1001,1002,1003,1008,   0,1033,1040,1041,
+  1042,1043,1047,   0,   0,1080,1081,1082,1086,1110,   0,   0,1124,1125,1126,1127,
+  1131,1133,   0,1147,1154,1155,1156,1161,1187,1188,1189,1193,   0,1219,1226,1227,
+  1228,1229,1233,   0,   0,1267,1268,1269,1273,1298,   0,1303, 943,1128, 944,1129,
+   954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149,   0,   0, 973,1158,
+   974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178,
+   994,1179,   0,   0,1004,1190,1005,1191,1006,1192,1014,1199,1007,   0,   0,   0,
+  1016,1201,1020,1206,   0,1022,1208,1025,1211,1023,1209,   0,   0,   0,   0,1032,
+  1218,1037,1223,1035,1221,   0,   0,   0,1044,1230,1045,1231,1049,1235,   0,   0,
+  1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,
+  1074,1261,   0,   0,1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,
+  1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310,   0,1053,1239,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1093,1280,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
-  1367,1342,1369,1339,1366,   0,1320,1347,1418,1419,1323,1350,   0,   0, 992,1177,
-  1018,1204,1055,1241,1416,1417,1415,1424,1202,   0,   0,   0, 987,1172,   0,   0,
-  1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
-  1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
-  1071,1257,1076,1263,   0,   0, 997,1182,   0,   0,   0,   0,   0,   0, 945,1130,
-   982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   8,   9,   0,  10,1425,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,1314,1427,   5,
-  1434,1438,1443,   0,1450,   0,1455,1461,1514,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0, 949,1134,1010,1195,1050,1236,1090,
+  1277,1341,1368,1340,1367,1342,1369,1339,1366,   0,1320,1347,1418,1419,1323,1350,
+     0,   0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,1202,   0,   0,   0,
+   987,1172,   0,   0,1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136,
+   979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,
+  1091,1278,1092,1279,1071,1257,1076,1263,   0,   0, 997,1182,   0,   0,   0,   0,
+     0,   0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   9,   0,  10,
+  1425,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+     0,1314,1427,   5,1434,1438,1443,   0,1450,   0,1455,1461,1514,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1446,1458,1468,1476,1480,1486,1517,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1446,1458,1468,1476,1480,1486,1517,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1489,1503,1494,1500,1508,   0,   0,   0,   0,1520,1521,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1526,1528,   0,1525,   0,   0,   0,1522,
-     0,   0,   0,   0,1536,1532,1539,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1534,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1556,   0,   0,   0,   0,   0,   0,1548,1550,   0,1547,   0,   0,   0,1567,
-     0,   0,   0,   0,1558,1554,1561,   0,   0,   0,   0,   0,   0,   0,1568,1569,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1529,1551,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1523,1545,1524,1546,   0,   0,1527,1549,
-     0,   0,1570,1571,1530,1552,1531,1553,   0,   0,1533,1555,1535,1557,1537,1559,
-     0,   0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564,   0,   0,
-  1543,1565,   0,   0,   0,   0,   0,   0,   0,   0,1606,1607,1609,1608,1610,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1613,   0,1611,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1612,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1489,1503,1494,1500,1508,   0,   0,   0,   0,1520,
+  1521,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1526,1528,   0,1525,
+     0,   0,   0,1522,   0,   0,   0,   0,1536,1532,1539,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1534,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1556,   0,   0,   0,   0,   0,   0,1548,1550,   0,1547,
+     0,   0,   0,1567,   0,   0,   0,   0,1558,1554,1561,   0,   0,   0,   0,   0,
+     0,   0,1568,1569,   0,   0,   0,   0,   0,   0,   0,   0,   0,1529,1551,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1523,1545,1524,1546,
+     0,   0,1527,1549,   0,   0,1570,1571,1530,1552,1531,1553,   0,   0,1533,1555,
+  1535,1557,1537,1559,   0,   0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,
+  1542,1564,   0,   0,1543,1565,   0,   0,   0,   0,   0,   0,   0,   0,1606,1607,
+  1609,1608,1610,   0,   0,   0,   0,   0,   0,   0,   0,   0,1613,   0,1611,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1612,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1620,   0,   0,   0,   0,   0,   0,   0,1623,   0,   0,1624,   0,   0,   0,
+     0,   0,   0,   0,   0,1620,   0,   0,   0,   0,   0,   0,   0,1623,   0,   0,
+  1624,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1614,1615,1616,1617,1618,1619,1621,1622,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1628,1629,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1625,1626,   0,1627,   0,   0,   0,1634,
+     0,   0,1635,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1630,1631,1632,   0,   0,1633,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1639,   0,   0,1638,1640,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1636,1637,   0,   0,   0,   0,   0,   0,
+  1641,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1642,1644,1643,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1645,   0,   0,   0,   0,   0,   0,   0,1646,   0,   0,   0,
+     0,   0,   0,1648,1649,   0,1647,1650,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1651,1653,1652,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1654,   0,1655,1657,1656,   0,   0,   0,   0,1659,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1660,   0,   0,   0,   0,1661,   0,
+     0,   0,   0,1662,   0,   0,   0,   0,1663,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1658,   0,   0,   0,   0,   0,   0,   0,   0,   0,1664,
+     0,1665,1673,   0,1674,   0,   0,   0,   0,   0,   0,   0,   0,1666,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1668,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1669,   0,   0,   0,   0,1670,   0,
+     0,   0,   0,1671,   0,   0,   0,   0,1672,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1667,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,1675,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,1676,   0,1677,   0,1678,   0,1679,   0,1680,   0,   0,   0,1681,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1614,1615,1616,1617,1618,1619,1621,1622,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1628,1629,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1625,1626,   0,1627,   0,   0,   0,1634,   0,   0,1635,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1630,1631,1632,   0,   0,1633,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1639,   0,   0,1638,1640,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1636,1637,   0,   0,   0,   0,   0,   0,1641,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1682,   0,1683,   0,   0,1684,1685,   0,1686,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 953,1138, 955,1140,
+   956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,
+  1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180,
+   998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,
+  1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,
+  1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,
+  1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,
+  1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,
+  1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,
+  1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,
+  1123,1312,1186,1260,1293,1305,   0,1394,   0,   0,   0,   0, 952,1137, 947,1132,
+  1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,
+  1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,
+  1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,
+  1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,
+  1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,
+  1117,1306,1116,1304,1112,1300,   0,   0,   0,   0,   0,   0,1471,1472,1701,1705,
+  1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,
+  1730,1732,   0,   0,1435,1436,1733,1735,1734,1736,   0,   0,1481,1482,1737,1741,
+  1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,
+  1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,
+  1778,1780,   0,   0,1451,1452,1781,1783,1782,1784,   0,   0,1504,1505,1785,1788,
+  1786,1789,1787,1790,   0,1459,   0,1791,   0,1792,   0,1793,1509,1510,1794,1798,
+  1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,1467,  21,1475,  22,
+  1479,  23,1485,  24,1493,  27,1499,  28,1507,  29,   0,   0,1704,1708,1709,1710,
+  1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,
+  1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,
+  1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,
+  1465,   0,1473,1825,1429,1428,1426,  12,1432,   0,  26,   0,   0,1315,1823,1484,
+  1466,   0,1483,1829,1433,  13,1437,  14,1441,1826,1827,1828,1488,1487,1513,  19,
+     0,   0,1492,1515,1445,1444,1442,  15,   0,1831,1832,1833,1502,1501,1516,  25,
+  1497,1498,1506,1518,1457,1456,1454,  17,1453,1313,  11,   3,   0,   0,1824,1512,
+  1519,   0,1511,1830,1449,  16,1460,  18,1464,   4,   0,   0,  30,  31,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1642,1644,1643,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1645,   0,   0,   0,   0,   0,   0,   0,1646,   0,   0,   0,   0,   0,   0,1648,
-  1649,   0,1647,1650,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1651,1653,1652,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1654,   0,1655,1657,1656,   0,   0,   0,   0,1659,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1660,   0,   0,   0,   0,1661,   0,   0,   0,   0,1662,
-     0,   0,   0,   0,1663,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1658,   0,   0,   0,   0,   0,   0,   0,   0,   0,1664,   0,1665,1673,   0,
-  1674,   0,   0,   0,   0,   0,   0,   0,   0,1666,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1668,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1669,   0,   0,   0,   0,1670,   0,   0,   0,   0,1671,
-     0,   0,   0,   0,1672,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1667,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1675,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1676,   0,
-  1677,   0,1678,   0,1679,   0,1680,   0,   0,   0,1681,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1682,   0,1683,   0,   0,1684,1685,   0,1686,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 953,1138, 955,1140, 956,1141, 957,1142,
-  1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
-   984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
-   999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
-  1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
-  1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
-  1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
-  1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
-  1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
-  1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
-  1293,1305,   0,1394,   0,   0,   0,   0, 952,1137, 947,1132,1317,1344,1316,1343,
-  1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
-   981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
-  1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
-  1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
-  1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
-  1112,1300,   0,   0,   0,   0,   0,   0,1471,1472,1701,1705,1702,1706,1703,1707,
-  1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732,   0,   0,
-  1435,1436,1733,1735,1734,1736,   0,   0,1481,1482,1737,1741,1738,1742,1739,1743,
-  1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
-  1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780,   0,   0,
-  1451,1452,1781,1783,1782,1784,   0,   0,1504,1505,1785,1788,1786,1789,1787,1790,
-     0,1459,   0,1791,   0,1792,   0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
-  1462,1463,1808,1812,1809,1813,1810,1814,1467,  21,1475,  22,1479,  23,1485,  24,
-  1493,  27,1499,  28,1507,  29,   0,   0,1704,1708,1709,1710,1711,1712,1713,1714,
-  1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
-  1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
-  1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465,   0,1473,1825,
-  1429,1428,1426,  12,1432,   0,  26,   0,   0,1315,1823,1484,1466,   0,1483,1829,
-  1433,  13,1437,  14,1441,1826,1827,1828,1488,1487,1513,  19,   0,   0,1492,1515,
-  1445,1444,1442,  15,   0,1831,1832,1833,1502,1501,1516,  25,1497,1498,1506,1518,
-  1457,1456,1454,  17,1453,1313,  11,   3,   0,   0,1824,1512,1519,   0,1511,1830,
-  1449,  16,1460,  18,1464,   4,   0,   0,  30,  31,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  20,   0,
-     0,   0,   2,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1834,1835,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1836,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1837,1839,1838,   0,   0,   0,   0,1840,   0,   0,   0,
-     0,1841,   0,   0,1842,   0,   0,   0,   0,   0,   0,   0,1843,   0,1844,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1845,   0,   0,1846,   0,   0,1847,
-     0,1848,   0,   0,   0,   0,   0,   0, 937,   0,1850,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1849, 936, 938,1851,1852,   0,   0,1853,1854,   0,   0,
-  1855,1856,   0,   0,   0,   0,   0,   0,1857,1858,   0,   0,1861,1862,   0,   0,
-  1863,1864,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1867,1868,1869,1870,1859,1860,1865,1866,   0,   0,   0,   0,
-     0,   0,1871,1872,1873,1874,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,  32,  33,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1875,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1877,   0,1878,   0,1879,   0,1880,   0,1881,   0,1882,   0,
-  1883,   0,1884,   0,1885,   0,1886,   0,1887,   0,1888,   0,   0,1889,   0,1890,
-     0,1891,   0,   0,   0,   0,   0,   0,1892,1893,   0,1894,1895,   0,1896,1897,
-     0,1898,1899,   0,1900,1901,   0,   0,   0,   0,   0,   0,1876,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1902,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1904,   0,1905,   0,1906,   0,1907,   0,1908,   0,1909,   0,
-  1910,   0,1911,   0,1912,   0,1913,   0,1914,   0,1915,   0,   0,1916,   0,1917,
-     0,1918,   0,   0,   0,   0,   0,   0,1919,1920,   0,1921,1922,   0,1923,1924,
-     0,1925,1926,   0,1927,1928,   0,   0,   0,   0,   0,   0,1903,   0,   0,1929,
-  1930,1931,1932,   0,   0,   0,1933,   0, 710, 385, 724, 715, 455, 103, 186, 825,
-   825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
-   649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
-   293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
-   781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
-   714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
-   648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
-   430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
-   135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
-   812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
-   726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
-   113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
-   774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
-   395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
-   305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
-   687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
-   568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
-   680, 767, 694, 295, 128, 210,   0,   0, 227,   0, 379,   0,   0, 150, 493, 525,
-   544, 551, 552, 556, 783, 576, 604,   0, 661,   0, 703,   0,   0, 735, 743,   0,
-     0,   0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
-   215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
-   477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
-   593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
-   777, 786, 790, 315, 869, 623,   0,   0, 102, 145, 134, 115, 129, 138, 165, 171,
-   207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
-   321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
-   456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
-   528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
-   695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
-   783, 784, 786, 787, 790, 802, 825, 848, 847, 857,  55,  65,  66, 883, 892, 916,
-   822, 824,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1586,   0,1605,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584,   0,
-  1585,1587,1588,1589,1591,   0,1592,   0,1593,1594,   0,1595,1596,   0,1598,1599,
-  1600,1601,1604,1582,1578,1590,1597,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1936,   0,1937,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1938,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1939,1940,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1941,1942,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1944,1943,   0,1945,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1946,1947,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1948,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1949,1950,1951,1952,1953,1954,1955,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1956,1957,1958,1960,1959,1961,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 106, 104, 107, 826, 114, 118, 119, 121,
-   123, 124, 127, 125,  34, 830, 130, 131, 132, 137, 827,  35, 133, 139, 829, 142,
-   143, 112, 144, 145, 924, 151, 152,  37, 157, 158, 159, 160,  38, 165, 166, 169,
-   171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
-   834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
-   208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
-   230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251,  39,
-    40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264,  41, 266,
-   270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282,  42, 283, 284, 285, 286,
-    43, 843,  44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300,  45, 852,
-   894, 302, 304,  46, 306, 309, 310, 312, 316,  48,  47, 317, 846, 318, 323, 324,
-   325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
-   849, 350, 348, 352, 354, 359, 850, 361, 358, 356,  49, 363, 365, 367, 364,  50,
-   369, 371, 851, 376, 386, 378,  53, 381,  52,  51, 140, 141, 387, 382, 614,  78,
-   388, 389, 390, 394, 392, 856,  54, 399, 396, 402, 404, 858, 405, 401, 407,  55,
-   408, 409, 410, 413, 859, 415,  56, 417, 860, 418,  57, 419, 422, 424, 425, 861,
-   840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
-   449, 450,  58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464,  59, 467,
-   470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
-   495, 497,  60, 498,  61,  61, 504, 505, 507, 508, 511,  62, 513, 874, 515, 875,
-   518, 844, 520, 876, 877, 878,  63,  64, 528, 880, 879, 881, 882, 530, 531, 531,
-   533,  66, 534,  67,  68, 884, 536, 538, 541,  69, 885, 549, 886, 887, 556, 559,
-    70, 561, 562, 563, 888, 889, 889, 567,  71, 890, 570, 571,  72, 891, 577,  73,
-   581, 579, 582, 893, 587,  74, 590, 592, 596,  75, 895, 896,  76, 897, 600, 898,
-   602, 605, 607, 899, 900, 609, 901, 611, 853,  77, 615, 616,  79, 617, 252, 902,
-   903, 854, 855, 621, 622, 731,  80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
-   632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906,  81,
-   653, 654, 656, 911, 657, 908,  82,  83, 909, 910,  84, 664, 665, 666, 667, 669,
-   668, 671, 670, 674, 672, 673, 675,  85, 677, 678,  86, 681, 682, 912, 685, 686,
-    87, 689,  36, 913, 914,  88,  89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
-   917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
-   756, 757, 755, 760, 761, 921, 762,  90, 764, 922,  91, 775, 279, 780, 923, 925,
-    92,  93, 785, 926,  94, 927, 787, 787, 789, 928, 792,  95, 796, 797, 798, 800,
-    96, 929, 802, 804, 806,  97,  98, 807, 930,  99, 931, 932, 933, 814, 100, 816,
-   817, 818, 819, 820, 821, 935,   0,   0,
+     0,   0,  20,   0,   0,   0,   2,   6,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1834,1835,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1836,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1837,1839,1838,   0,   0,   0,   0,
+  1840,   0,   0,   0,   0,1841,   0,   0,1842,   0,   0,   0,   0,   0,   0,   0,
+  1843,   0,1844,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1845,   0,   0,
+  1846,   0,   0,1847,   0,1848,   0,   0,   0,   0,   0,   0, 937,   0,1850,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1849, 936, 938,1851,1852,   0,   0,
+  1853,1854,   0,   0,1855,1856,   0,   0,   0,   0,   0,   0,1857,1858,   0,   0,
+  1861,1862,   0,   0,1863,1864,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1867,1868,1869,1870,1859,1860,1865,1866,
+     0,   0,   0,   0,   0,   0,1871,1872,1873,1874,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,  32,  33,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1875,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1877,   0,1878,   0,1879,   0,1880,   0,
+  1881,   0,1882,   0,1883,   0,1884,   0,1885,   0,1886,   0,1887,   0,1888,   0,
+     0,1889,   0,1890,   0,1891,   0,   0,   0,   0,   0,   0,1892,1893,   0,1894,
+  1895,   0,1896,1897,   0,1898,1899,   0,1900,1901,   0,   0,   0,   0,   0,   0,
+  1876,   0,   0,   0,   0,   0,   0,   0,   0,   0,1902,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1904,   0,1905,   0,1906,   0,1907,   0,
+  1908,   0,1909,   0,1910,   0,1911,   0,1912,   0,1913,   0,1914,   0,1915,   0,
+     0,1916,   0,1917,   0,1918,   0,   0,   0,   0,   0,   0,1919,1920,   0,1921,
+  1922,   0,1923,1924,   0,1925,1926,   0,1927,1928,   0,   0,   0,   0,   0,   0,
+  1903,   0,   0,1929,1930,1931,1932,   0,   0,   0,1933,   0, 710, 385, 724, 715,
+   455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738,
+   411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658,
+   692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527,
+   606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299,
+   573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613,
+   149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174,
+   542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349,
+   632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374,
+   463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476,
+   509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311,
+   353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782,
+   788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737,
+   823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769,
+   122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432,
+   501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813,
+   397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578,
+   256, 435, 383, 729, 680, 767, 694, 295, 128, 210,   0,   0, 227,   0, 379,   0,
+     0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604,   0, 661,   0, 703,   0,
+     0, 735, 743,   0,   0,   0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166,
+   169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381,
+   404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555,
+   561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706,
+   716, 717, 733, 735, 777, 786, 790, 315, 869, 623,   0,   0, 102, 145, 134, 115,
+   129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296,
+   303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389,
+   393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514,
+   521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637,
+   647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736,
+   747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, 847, 857,  55,  65,
+    66, 883, 892, 916, 822, 824,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1586,   0,1605,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,
+  1581,1583,1584,   0,1585,1587,1588,1589,1591,   0,1592,   0,1593,1594,   0,1595,
+  1596,   0,1598,1599,1600,1601,1604,1582,1578,1590,1597,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1936,   0,1937,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1938,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1939,1940,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1941,1942,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1944,1943,   0,1945,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1946,1947,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1948,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1949,1950,1951,1952,1953,1954,
+  1955,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1956,1957,1958,1960,1959,1961,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 106, 104, 107, 826,
+   114, 118, 119, 121, 123, 124, 127, 125,  34, 830, 130, 131, 132, 137, 827,  35,
+   133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152,  37, 157, 158, 159, 160,
+    38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182,
+   833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201,
+   203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222,
+   223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248,
+   249, 246, 251,  39,  40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263,
+   301, 264,  41, 266, 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282,  42,
+   283, 284, 285, 286,  43, 843,  44, 289, 290, 291, 293, 934, 298, 845, 845, 621,
+   300, 300,  45, 852, 894, 302, 304,  46, 306, 309, 310, 312, 316,  48,  47, 317,
+   846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339,
+   342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, 358, 356,  49, 363,
+   365, 367, 364,  50, 369, 371, 851, 376, 386, 378,  53, 381,  52,  51, 140, 141,
+   387, 382, 614,  78, 388, 389, 390, 394, 392, 856,  54, 399, 396, 402, 404, 858,
+   405, 401, 407,  55, 408, 409, 410, 413, 859, 415,  56, 417, 860, 418,  57, 419,
+   422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439,
+   442, 443, 864, 436, 449, 450,  58, 454, 453, 865, 447, 460, 866, 867, 461, 466,
+   465, 464,  59, 467, 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871,
+   488, 489, 872, 873, 495, 497,  60, 498,  61,  61, 504, 505, 507, 508, 511,  62,
+   513, 874, 515, 875, 518, 844, 520, 876, 877, 878,  63,  64, 528, 880, 879, 881,
+   882, 530, 531, 531, 533,  66, 534,  67,  68, 884, 536, 538, 541,  69, 885, 549,
+   886, 887, 556, 559,  70, 561, 562, 563, 888, 889, 889, 567,  71, 890, 570, 571,
+    72, 891, 577,  73, 581, 579, 582, 893, 587,  74, 590, 592, 596,  75, 895, 896,
+    76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, 853,  77, 615, 616,
+    79, 617, 252, 902, 903, 854, 855, 621, 622, 731,  80, 627, 626, 628, 164, 629,
+   630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645,
+   905, 907, 906,  81, 653, 654, 656, 911, 657, 908,  82,  83, 909, 910,  84, 664,
+   665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675,  85, 677, 678,  86, 681,
+   682, 912, 685, 686,  87, 689,  36, 913, 914,  88,  89, 696, 702, 709, 711, 915,
+   712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742,
+   744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762,  90, 764, 922,  91, 775,
+   279, 780, 923, 925,  92,  93, 785, 926,  94, 927, 787, 787, 789, 928, 792,  95,
+   796, 797, 798, 800,  96, 929, 802, 804, 806,  97,  98, 807, 930,  99, 931, 932,
+   933, 814, 100, 816, 817, 818, 819, 820, 821, 935,   0,   0,
 };
 static const int16_t
 _hb_ucd_i16[92] =
@@ -4400,12 +4403,12 @@
 static inline uint_fast8_t
 _hb_ucd_gc (unsigned u)
 {
-  return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+  return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
 }
 static inline uint_fast8_t
 _hb_ucd_ccc (unsigned u)
 {
-  return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+  return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
 }
 static inline unsigned
 _hb_ucd_b4 (const uint8_t* a, unsigned i)
@@ -4415,24 +4418,24 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9684+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[9356+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9692+(((_hb_ucd_u8[9460+(((_hb_ucd_u8[9364+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918000u?_hb_ucd_u8[11118+(((_hb_ucd_u16[4024+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10382+(((_hb_ucd_u8[9932+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
+  return u<918000u?_hb_ucd_u8[11126+(((_hb_ucd_u16[4040+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10390+(((_hb_ucd_u8[9940+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[6728+(((_hb_ucd_u8[13944+(((_hb_ucd_u8[13562+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[6748+(((_hb_ucd_u8[13952+(((_hb_ucd_u8[13570+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 
 #else
 
 static const uint8_t
-_hb_ucd_u8[13370] =
+_hb_ucd_u8[13386] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7,  7, 11, 12, 12, 12, 13,
@@ -4440,7 +4443,7 @@
     7, 24, 21, 21, 21, 25, 26, 27, 21, 28, 29, 30, 31, 32, 33, 34,
     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 35, 21, 36,
-    7,  7,  7,  7, 35, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    7,  7,  7,  7, 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4462,7 +4465,7 @@
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-   37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   38, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
@@ -4503,8 +4506,9 @@
    34,192,193,111,111,111,111,111,130,194,195,111, 34,196,111,111,
    67, 67,197, 67, 67,111, 67,198, 67, 67, 67, 67, 67, 67, 67, 67,
    67, 67, 67, 67, 67, 67, 67,199,111,111,111,111,111,111,111,111,
-   34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,
    34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,
   200,111,188,188,111,111,111,111,111,111,111,111,111,111,111,111,
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
     7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
@@ -4967,7 +4971,7 @@
    31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 66, 67, 31, 31,
    31, 31, 68, 31, 31, 31, 31, 31, 31, 31, 31, 69, 70, 71, 17, 17,
    72, 73, 31, 74, 75, 76, 77, 78, 79, 31, 80, 81, 17, 82, 17, 17,
-   17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31,
+   17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 23, 83, 31, 31, 31, 31,
    23, 83, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
    31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
    31, 31, 31, 31, 84,  0,  0,  1,  0,  1,  2,  3,  0,  1,  2,  3,
@@ -5597,12 +5601,12 @@
 static inline uint_fast8_t
 _hb_ucd_gc (unsigned u)
 {
-  return u<1114112u?_hb_ucd_u8[5080+(((_hb_ucd_u8[1152+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+  return u<1114112u?_hb_ucd_u8[5096+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
 }
 static inline uint_fast8_t
 _hb_ucd_ccc (unsigned u)
 {
-  return u<125259u?_hb_ucd_u8[7038+(((_hb_ucd_u8[6482+(((_hb_ucd_u8[6022+(((_hb_ucd_u8[5670+(((_hb_ucd_u8[5424+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+  return u<125259u?_hb_ucd_u8[7054+(((_hb_ucd_u8[6498+(((_hb_ucd_u8[6038+(((_hb_ucd_u8[5686+(((_hb_ucd_u8[5440+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
 }
 static inline unsigned
 _hb_ucd_b4 (const uint8_t* a, unsigned i)
@@ -5612,17 +5616,17 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7930+(((_hb_ucd_u8[7698+(((_hb_ucd_u8[7602+(((_hb_ucd_b4(7538+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7946+(((_hb_ucd_u8[7714+(((_hb_ucd_u8[7618+(((_hb_ucd_b4(7554+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918016u?_hb_ucd_u8[11228+(((_hb_ucd_u8[10264+(((_hb_ucd_u8[9276+(((_hb_ucd_u8[8596+(((_hb_ucd_u8[8292+(((_hb_ucd_u8[8178+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
+  return u<918016u?_hb_ucd_u8[11244+(((_hb_ucd_u8[10280+(((_hb_ucd_u8[9292+(((_hb_ucd_u8[8612+(((_hb_ucd_u8[8308+(((_hb_ucd_u8[8194+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12570+(((_hb_ucd_u8[12188+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12586+(((_hb_ucd_u8[12204+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 #endif
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh	2024-01-16 16:19:00.000000000 +0000
@@ -7,13 +7,13 @@
  * on file with this header:
  *
  * # emoji-data.txt
- * # Date: 2022-08-02, 00:26:10 GMT
- * # © 2022 Unicode®, Inc.
+ * # Date: 2023-02-01, 02:22:54 GMT
+ * # © 2023 Unicode®, Inc.
  * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
  * # For terms of use, see https://www.unicode.org/terms_of_use.html
  * #
  * # Emoji Data for UTS #51
- * # Used with Emoji Version 15.0 and subsequent minor revisions (if any)
+ * # Used with Emoji Version 15.1 and subsequent minor revisions (if any)
  * #
  * # For documentation and usage, see https://www.unicode.org/reports/tr51
  */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-vector.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-vector.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-vector.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-vector.hh	2024-01-16 16:19:00.000000000 +0000
@@ -54,7 +54,7 @@
   hb_vector_t (const Iterable &o) : hb_vector_t ()
   {
     auto iter = hb_iter (o);
-    if (iter.is_random_access_iterator)
+    if (iter.is_random_access_iterator || iter.has_fast_len)
       alloc (hb_len (iter), true);
     hb_copy (iter, *this);
   }
@@ -62,7 +62,19 @@
   {
     alloc (o.length, true);
     if (unlikely (in_error ())) return;
-    copy_vector (o);
+    copy_array (o.as_array ());
+  }
+  hb_vector_t (array_t o) : hb_vector_t ()
+  {
+    alloc (o.length, true);
+    if (unlikely (in_error ())) return;
+    copy_array (o);
+  }
+  hb_vector_t (c_array_t o) : hb_vector_t ()
+  {
+    alloc (o.length, true);
+    if (unlikely (in_error ())) return;
+    copy_array (o);
   }
   hb_vector_t (hb_vector_t &&o)
   {
@@ -74,7 +86,7 @@
   ~hb_vector_t () { fini (); }
 
   public:
-  int allocated = 0; /* == -1 means allocation failed. */
+  int allocated = 0; /* < 0 means allocation failed. */
   unsigned int length = 0;
   public:
   Type *arrayZ = nullptr;
@@ -90,19 +102,21 @@
 
   void fini ()
   {
-    shrink_vector (0);
-    hb_free (arrayZ);
+    /* We allow a hack to make the vector point to a foreign array
+     * by the user. In that case length/arrayZ are non-zero but
+     * allocated is zero. Don't free anything. */
+    if (allocated)
+    {
+      shrink_vector (0);
+      hb_free (arrayZ);
+    }
     init ();
   }
 
   void reset ()
   {
     if (unlikely (in_error ()))
-      /* Big Hack! We don't know the true allocated size before
-       * an allocation failure happened. But we know it was at
-       * least as big as length. Restore it to that and continue
-       * as if error did not happen. */
-      allocated = length;
+      reset_error ();
     resize (0);
   }
 
@@ -119,7 +133,7 @@
     alloc (o.length, true);
     if (unlikely (in_error ())) return *this;
 
-    copy_vector (o);
+    copy_array (o.as_array ());
 
     return *this;
   }
@@ -191,47 +205,38 @@
   Type *push ()
   {
     if (unlikely (!resize (length + 1)))
-      return &Crap (Type);
+      return std::addressof (Crap (Type));
     return std::addressof (arrayZ[length - 1]);
   }
-  template ::value &&
-                          std::is_copy_assignable::value)>
-  Type *push (T&& v)
-  {
-    Type *p = push ();
-    if (p == &Crap (Type))
-      // If push failed to allocate then don't copy v, since this may cause
-      // the created copy to leak memory since we won't have stored a
-      // reference to it.
-      return p;
-    *p = std::forward (v);
-    return p;
-  }
-  template ::value)>
-  Type *push (T&& v)
+  template  Type *push (Args&&... args)
   {
-    if (unlikely (!alloc (length + 1)))
+    if (unlikely ((int) length >= allocated && !alloc (length + 1)))
       // If push failed to allocate then don't copy v, since this may cause
       // the created copy to leak memory since we won't have stored a
       // reference to it.
-      return &Crap (Type);
+      return std::addressof (Crap (Type));
 
     /* Emplace. */
-    length++;
-    Type *p = std::addressof (arrayZ[length - 1]);
-    return new (p) Type (std::forward (v));
+    Type *p = std::addressof (arrayZ[length++]);
+    return new (p) Type (std::forward (args)...);
   }
 
   bool in_error () const { return allocated < 0; }
+  void set_error ()
+  {
+    assert (allocated >= 0);
+    allocated = -allocated - 1;
+  }
+  void reset_error ()
+  {
+    assert (allocated < 0);
+    allocated = -(allocated + 1);
+  }
 
   template 
   Type *
-  realloc_vector (unsigned new_allocated)
+  realloc_vector (unsigned new_allocated, hb_priority<0>)
   {
     if (!new_allocated)
     {
@@ -243,7 +248,7 @@
   template 
   Type *
-  realloc_vector (unsigned new_allocated)
+  realloc_vector (unsigned new_allocated, hb_priority<0>)
   {
     if (!new_allocated)
     {
@@ -263,47 +268,66 @@
     }
     return new_array;
   }
+  /* Specialization for hb_vector_t> to speed up. */
+  template ) ||
+                          hb_is_same (T, hb_array_t ))>
+  Type *
+  realloc_vector (unsigned new_allocated, hb_priority<1>)
+  {
+    if (!new_allocated)
+    {
+      hb_free (arrayZ);
+      return nullptr;
+    }
+    return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
+  }
 
   template 
   void
-  grow_vector (unsigned size)
+  grow_vector (unsigned size, hb_priority<0>)
   {
-    memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+    hb_memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
     length = size;
   }
   template 
   void
-  grow_vector (unsigned size)
+  grow_vector (unsigned size, hb_priority<0>)
   {
-    while (length < size)
-    {
-      length++;
-      new (std::addressof (arrayZ[length - 1])) Type ();
-    }
+    for (; length < size; length++)
+      new (std::addressof (arrayZ[length])) Type ();
+  }
+  /* Specialization for hb_vector_t> to speed up. */
+  template ) ||
+                          hb_is_same (T, hb_array_t ))>
+  void
+  grow_vector (unsigned size, hb_priority<1>)
+  {
+    hb_memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+    length = size;
   }
 
   template 
   void
-  copy_vector (const hb_vector_t &other)
+  copy_array (hb_array_t other)
   {
     length = other.length;
-#ifndef HB_OPTIMIZE_SIZE
-    if (sizeof (T) >= sizeof (long long))
+    if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long))
       /* This runs faster because of alignment. */
       for (unsigned i = 0; i < length; i++)
         arrayZ[i] = other.arrayZ[i];
     else
-#endif
        hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
   }
   template ::value)>
   void
-  copy_vector (const hb_vector_t &other)
+  copy_array (hb_array_t other)
   {
     length = 0;
     while (length < other.length)
@@ -318,7 +342,7 @@
                           std::is_default_constructible::value &&
                           std::is_copy_assignable::value)>
   void
-  copy_vector (const hb_vector_t &other)
+  copy_array (hb_array_t other)
   {
     length = 0;
     while (length < other.length)
@@ -332,11 +356,15 @@
   void
   shrink_vector (unsigned size)
   {
-    while ((unsigned) length > size)
+    assert (size <= length);
+    if (!std::is_trivially_destructible::value)
     {
-      arrayZ[(unsigned) length - 1].~Type ();
-      length--;
+      unsigned count = length - size;
+      Type *p = arrayZ + length - 1;
+      while (count--)
+        p--->~Type ();
     }
+    length = size;
   }
 
   void
@@ -383,18 +411,18 @@
 
     if (unlikely (overflows))
     {
-      allocated = -1;
+      set_error ();
       return false;
     }
 
-    Type *new_array = realloc_vector (new_allocated);
+    Type *new_array = realloc_vector (new_allocated, hb_prioritize);
 
     if (unlikely (new_allocated && !new_array))
     {
       if (new_allocated <= (unsigned) allocated)
         return true; // shrinking failed; it's okay; happens in our fuzzer
 
-      allocated = -1;
+      set_error ();
       return false;
     }
 
@@ -413,7 +441,7 @@
     if (size > length)
     {
       if (initialize)
-        grow_vector (size);
+        grow_vector (size, hb_prioritize);
     }
     else if (size < length)
     {
@@ -432,7 +460,7 @@
   Type pop ()
   {
     if (!length) return Null (Type);
-    Type v {std::move (arrayZ[length - 1])};
+    Type v (std::move (arrayZ[length - 1]));
     arrayZ[length - 1].~Type ();
     length--;
     return v;
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-version.h openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-version.h
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb-version.h	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb-version.h	2024-01-16 16:19:00.000000000 +0000
@@ -41,7 +41,7 @@
  *
  * The major component of the library version available at compile-time.
  */
-#define HB_VERSION_MAJOR 7
+#define HB_VERSION_MAJOR 8
 /**
  * HB_VERSION_MINOR:
  *
@@ -53,14 +53,14 @@
  *
  * The micro component of the library version available at compile-time.
  */
-#define HB_VERSION_MICRO 0
+#define HB_VERSION_MICRO 2
 
 /**
  * HB_VERSION_STRING:
  *
  * A string literal containing the library version available at compile-time.
  */
-#define HB_VERSION_STRING "7.2.0"
+#define HB_VERSION_STRING "8.2.2"
 
 /**
  * HB_VERSION_ATLEAST:
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb.hh openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb.hh
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libharfbuzz/hb.hh	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libharfbuzz/hb.hh	2024-01-16 16:19:00.000000000 +0000
@@ -64,6 +64,7 @@
 #pragma GCC diagnostic error   "-Wbitwise-instead-of-logical"
 #pragma GCC diagnostic error   "-Wcast-align"
 #pragma GCC diagnostic error   "-Wcast-function-type"
+#pragma GCC diagnostic error   "-Wconstant-conversion"
 #pragma GCC diagnostic error   "-Wcomma"
 #pragma GCC diagnostic error   "-Wdelete-non-virtual-dtor"
 #pragma GCC diagnostic error   "-Wembedded-directive"
@@ -255,8 +256,8 @@
 #endif
 
 #if defined(__OPTIMIZE__) && hb_has_builtin(__builtin_expect)
-#define likely(expr) (__builtin_expect (!!(expr), 1))
-#define unlikely(expr) (__builtin_expect (!!(expr), 0))
+#define likely(expr) __builtin_expect (bool(expr), 1)
+#define unlikely(expr) __builtin_expect (bool(expr), 0)
 #else
 #define likely(expr) (expr)
 #define unlikely(expr) (expr)
@@ -315,6 +316,14 @@
 #define __restrict
 #endif
 
+#ifndef HB_ALWAYS_INLINE
+#if defined(_MSC_VER)
+#define HB_ALWAYS_INLINE __forceinline
+#else
+#define HB_ALWAYS_INLINE __attribute__((always_inline)) inline
+#endif
+#endif
+
 /*
  * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
  * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c openjdk-21-21.0.2+13/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c	2024-01-16 16:19:00.000000000 +0000
@@ -1132,6 +1132,10 @@
         return;
     }
     num_bytes += sb->remaining_skip;
+    // Check for overflow if remaining_skip value is too large
+    if (num_bytes < 0) {
+        return;
+    }
     sb->remaining_skip = 0;
 
     /* First the easy case where we are skipping <= the current contents. */
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c openjdk-21-21.0.2+13/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c
--- openjdk-21-21.0.1+12/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c	2024-01-16 16:19:00.000000000 +0000
@@ -406,6 +406,10 @@
         return;
     }
     num_bytes += src->remaining_skip;
+    // Check for overflow if remaining_skip value is too large
+    if (num_bytes < 0) {
+        return;
+    }
     src->remaining_skip = 0;
     ret = (int)src->pub.bytes_in_buffer; /* this conversion is safe, because capacity of the buffer is limited by jnit */
     if (ret >= num_bytes) {
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c openjdk-21-21.0.2+13/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c
--- openjdk-21-21.0.1+12/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c	2024-01-16 16:19:00.000000000 +0000
@@ -2299,6 +2299,7 @@
 
     pRect = (RECT_T *)SAFE_SIZE_ARRAY_ALLOC(malloc, worstBufferSize, sizeof(RECT_T));
     if (!pRect) {
+        (*env)->ReleaseIntArrayElements(env, bitmap, values, JNI_ABORT);
         return;
     }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/TMSchema.java openjdk-21-21.0.2+13/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/TMSchema.java
--- openjdk-21-21.0.1+12/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/TMSchema.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/TMSchema.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -40,10 +40,13 @@
 
 package com.sun.java.swing.plaf.windows;
 
-import java.awt.*;
-import java.util.*;
-
-import javax.swing.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.Point;
+import java.util.EnumMap;
+import javax.swing.JComponent;
 
 import sun.awt.windows.ThemeReader;
 
@@ -55,7 +58,7 @@
  *
  * @author Leif Samuelsson
  */
-class TMSchema {
+public final class TMSchema {
 
     /**
      * An enumeration of the various Windows controls (also known as
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java openjdk-21-21.0.2+13/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java
--- openjdk-21-21.0.1+12/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -40,14 +40,41 @@
 
 package com.sun.java.swing.plaf.windows;
 
-import java.awt.*;
-import java.awt.image.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
 import java.security.AccessController;
-import java.util.*;
+import java.util.HashMap;
 
-import javax.swing.*;
-import javax.swing.border.*;
-import javax.swing.plaf.*;
+import javax.swing.AbstractButton;
+import javax.swing.CellRendererPane;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JRadioButton;
+import javax.swing.JToolBar;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.AbstractBorder;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.InsetsUIResource;
+import javax.swing.plaf.UIResource;
 import javax.swing.text.JTextComponent;
 
 import sun.awt.image.SunWritableRaster;
@@ -55,8 +82,10 @@
 import sun.security.action.GetPropertyAction;
 import sun.swing.CachedPainter;
 
-import static com.sun.java.swing.plaf.windows.TMSchema.*;
-
+import static com.sun.java.swing.plaf.windows.TMSchema.Part;
+import static com.sun.java.swing.plaf.windows.TMSchema.Prop;
+import static com.sun.java.swing.plaf.windows.TMSchema.State;
+import static com.sun.java.swing.plaf.windows.TMSchema.TypeEnum;
 
 /**
  * Implements Windows XP Styles for the Windows Look and Feel.
@@ -675,6 +704,11 @@
             w = bi.getWidth();
             h = bi.getHeight();
 
+            // Get DPI to pass further to ThemeReader.paintBackground()
+            Graphics2D g2d = (Graphics2D) g;
+            AffineTransform at = g2d.getTransform();
+            int dpi = (int)(at.getScaleX() * 96);
+
             WritableRaster raster = bi.getRaster();
             DataBufferInt dbi = (DataBufferInt)raster.getDataBuffer();
             // Note that stealData() requires a markDirty() afterwards
@@ -682,7 +716,8 @@
             ThemeReader.paintBackground(SunWritableRaster.stealData(dbi, 0),
                                         part.getControlName(c), part.getValue(),
                                         State.getValue(part, state),
-                                        0, 0, w, h, w);
+                                        0, 0, w, h, w, dpi);
+
             SunWritableRaster.markDirty(dbi);
         }
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java openjdk-21-21.0.2+13/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java
--- openjdk-21-21.0.1+12/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -30,11 +30,14 @@
 import java.awt.Insets;
 import java.awt.Point;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import static com.sun.java.swing.plaf.windows.TMSchema.Part;
+
 /**
  * Implements Theme Support for Windows XP.
  *
@@ -44,7 +47,24 @@
  */
 public final class ThemeReader {
 
-    private static final Map widgetToTheme = new HashMap<>();
+    private static final int defaultDPI = 96;
+
+    /**
+     * List of widgets for which we need to get the part size for the current DPI.
+     */
+    private static final  List partSizeWidgets =
+            List.of("MENU", "BUTTON");
+
+    /**
+     * List of widget parts for which we need to get the part size for the current DPI.
+     */
+    private static final List partSizeWidgetParts =
+            List.of(Part.BP_RADIOBUTTON.getValue(),
+                    Part.BP_CHECKBOX.getValue(),
+                    Part.MP_POPUPCHECK.getValue());
+
+    private static final Map> dpiAwareWidgetToTheme
+            = new HashMap<>();
 
     // lock for the cache
     // reading should be done with readLock
@@ -80,28 +100,30 @@
         return xpStyleEnabled;
     }
 
+    private static Long openThemeImpl(String widget, int dpi) {
+       Long theme;
+       int i = widget.indexOf("::");
+       if (i > 0) {
+           // We're using the syntax "subAppName::controlName" here, as used by msstyles.
+           // See documentation for SetWindowTheme on MSDN.
+           setWindowTheme(widget.substring(0, i));
+           theme = openTheme(widget.substring(i + 2), dpi);
+           setWindowTheme(null);
+       } else {
+           theme = openTheme(widget, dpi);
+       }
+       return theme;
+    }
+
     // this should be called only with writeLock held
-    private static Long getThemeImpl(String widget) {
-        Long theme = widgetToTheme.get(widget);
-        if (theme == null) {
-            int i = widget.indexOf("::");
-            if (i > 0) {
-                // We're using the syntax "subAppName::controlName" here, as used by msstyles.
-                // See documentation for SetWindowTheme on MSDN.
-                setWindowTheme(widget.substring(0, i));
-                theme = openTheme(widget.substring(i+2));
-                setWindowTheme(null);
-            } else {
-                theme = openTheme(widget);
-            }
-            widgetToTheme.put(widget, theme);
-        }
-        return theme;
+    private static Long getThemeImpl(String widget, int dpi) {
+       return dpiAwareWidgetToTheme.computeIfAbsent(dpi, key -> new HashMap<>())
+                .computeIfAbsent(widget, w -> openThemeImpl(widget, dpi));
     }
 
     // returns theme value
     // this method should be invoked with readLock locked
-    private static Long getTheme(String widget) {
+    private static Long getTheme(String widget, int dpi) {
         if (!isThemed) {
             throw new IllegalStateException("Themes are not loaded");
         }
@@ -111,10 +133,12 @@
             try {
                 if (!valid) {
                     // Close old themes.
-                    for (Long value : widgetToTheme.values()) {
-                        closeTheme(value);
+                    for (Map dpiVal : dpiAwareWidgetToTheme.values()) {
+                        for (Long value : dpiVal.values()) {
+                            closeTheme(value);
+                        }
                     }
-                    widgetToTheme.clear();
+                    dpiAwareWidgetToTheme.clear();
                     valid = true;
                 }
             } finally {
@@ -123,13 +147,20 @@
             }
         }
 
+        Long theme = null;
+
+        Map widgetToTheme = dpiAwareWidgetToTheme.get(dpi);
+
+        if (widgetToTheme != null) {
+            theme = widgetToTheme.get(widget);
+        }
+
         // mostly copied from the javadoc for ReentrantReadWriteLock
-        Long theme = widgetToTheme.get(widget);
         if (theme == null) {
             readLock.unlock();
             writeLock.lock();
             try {
-                theme = getThemeImpl(widget);
+                theme = getThemeImpl(widget, dpi);
             } finally {
                 readLock.lock();
                 writeLock.unlock();// Unlock write, still hold read
@@ -139,14 +170,23 @@
     }
 
     private static native void paintBackground(int[] buffer, long theme,
-                                               int part, int state, int x,
-                                               int y, int w, int h, int stride);
+                                               int part, int state,
+                                               int rectRight, int rectBottom,
+                                               int w, int h, int stride);
 
     public static void paintBackground(int[] buffer, String widget,
-           int part, int state, int x, int y, int w, int h, int stride) {
+           int part, int state, int x, int y, int w, int h, int stride, int dpi) {
         readLock.lock();
         try {
-            paintBackground(buffer, getTheme(widget), part, state, x, y, w, h, stride);
+            /* For widgets and parts in the lists, we get the part size
+            for the current screen DPI to scale them better. */
+            Dimension d = (partSizeWidgets.contains(widget)
+                          && partSizeWidgetParts.contains(Integer.valueOf(part)))
+                          ? getPartSize(getTheme(widget, dpi), part, state)
+                          : new Dimension(w, h);
+
+            paintBackground(buffer, getTheme(widget, dpi), part, state,
+                            d.width, d.height, w, h, stride);
         } finally {
             readLock.unlock();
         }
@@ -158,7 +198,7 @@
     public static Insets getThemeMargins(String widget, int part, int state, int marginType) {
         readLock.lock();
         try {
-            return getThemeMargins(getTheme(widget), part, state, marginType);
+            return getThemeMargins(getTheme(widget, defaultDPI), part, state, marginType);
         } finally {
             readLock.unlock();
         }
@@ -169,7 +209,7 @@
     public static boolean isThemePartDefined(String widget, int part, int state) {
         readLock.lock();
         try {
-            return isThemePartDefined(getTheme(widget), part, state);
+            return isThemePartDefined(getTheme(widget, defaultDPI), part, state);
         } finally {
             readLock.unlock();
         }
@@ -181,7 +221,7 @@
     public static Color getColor(String widget, int part, int state, int property) {
         readLock.lock();
         try {
-            return getColor(getTheme(widget), part, state, property);
+            return getColor(getTheme(widget, defaultDPI), part, state, property);
         } finally {
             readLock.unlock();
         }
@@ -193,7 +233,7 @@
     public static int getInt(String widget, int part, int state, int property) {
         readLock.lock();
         try {
-            return getInt(getTheme(widget), part, state, property);
+            return getInt(getTheme(widget, defaultDPI), part, state, property);
         } finally {
             readLock.unlock();
         }
@@ -205,7 +245,7 @@
     public static int getEnum(String widget, int part, int state, int property) {
         readLock.lock();
         try {
-            return getEnum(getTheme(widget), part, state, property);
+            return getEnum(getTheme(widget, defaultDPI), part, state, property);
         } finally {
             readLock.unlock();
         }
@@ -218,7 +258,7 @@
                                      int property) {
         readLock.lock();
         try {
-            return getBoolean(getTheme(widget), part, state, property);
+            return getBoolean(getTheme(widget, defaultDPI), part, state, property);
         } finally {
             readLock.unlock();
         }
@@ -229,7 +269,7 @@
     public static boolean getSysBoolean(String widget, int property) {
         readLock.lock();
         try {
-            return getSysBoolean(getTheme(widget), property);
+            return getSysBoolean(getTheme(widget, defaultDPI), property);
         } finally {
             readLock.unlock();
         }
@@ -241,7 +281,7 @@
     public static Point getPoint(String widget, int part, int state, int property) {
         readLock.lock();
         try {
-            return getPoint(getTheme(widget), part, state, property);
+            return getPoint(getTheme(widget, defaultDPI), part, state, property);
         } finally {
             readLock.unlock();
         }
@@ -254,7 +294,7 @@
                                         int property) {
         readLock.lock();
         try {
-            return getPosition(getTheme(widget), part,state,property);
+            return getPosition(getTheme(widget, defaultDPI), part,state,property);
         } finally {
             readLock.unlock();
         }
@@ -266,13 +306,13 @@
     public static Dimension getPartSize(String widget, int part, int state) {
         readLock.lock();
         try {
-            return getPartSize(getTheme(widget), part, state);
+            return getPartSize(getTheme(widget, defaultDPI), part, state);
         } finally {
             readLock.unlock();
         }
     }
 
-    private static native long openTheme(String widget);
+    private static native long openTheme(String widget, int dpi);
 
     private static native void closeTheme(long theme);
 
@@ -285,8 +325,9 @@
                                        int stateFrom, int stateTo, int propId) {
         readLock.lock();
         try {
-            return getThemeTransitionDuration(getTheme(widget),
-                                              part, stateFrom, stateTo, propId);
+            return getThemeTransitionDuration(getTheme(widget, defaultDPI),
+                                              part, stateFrom, stateTo,
+                                              propId);
         } finally {
             readLock.unlock();
         }
@@ -299,8 +340,9 @@
                     int part, int state, int boundingWidth, int boundingHeight) {
         readLock.lock();
         try {
-            return getThemeBackgroundContentMargins(getTheme(widget),
-                                    part, state, boundingWidth, boundingHeight);
+            return getThemeBackgroundContentMargins(getTheme(widget, defaultDPI),
+                                                    part, state,
+                                                    boundingWidth, boundingHeight);
         } finally {
             readLock.unlock();
         }
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
--- openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp	2024-01-16 16:19:00.000000000 +0000
@@ -46,7 +46,7 @@
 typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
         int iPartId, int iStateId, const RECT *pRect,  const RECT *pClipRect);
 
-typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
+typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
 
 typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
           int iPartId, int iStateId, LPCWSTR pszText, int iCharCount,
@@ -90,7 +90,7 @@
                 (HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
                  int iPropId, DWORD *pdwDuration);
 
-static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
+static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
 static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL;
 static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL;
 static PFNDRAWTHEMETEXT DrawThemeTextFunc = NULL;
@@ -116,8 +116,8 @@
     DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
     if(hModThemes) {
         DTRACE_PRINTLN("Loaded UxTheme.dll\n");
-        OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
-                                                        "OpenThemeData");
+        OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
+                                   hModThemes, "OpenThemeDataForDpi");
         DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
                                         hModThemes, "DrawThemeBackground");
         CloseThemeDataFunc = (PFNCLOSETHEMEDATA)GetProcAddress(
@@ -152,7 +152,7 @@
             (PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
                                         "GetThemeTransitionDuration");
 
-        if(OpenThemeDataFunc
+        if(OpenThemeDataForDpiFunc
            && DrawThemeBackgroundFunc
            && CloseThemeDataFunc
            && DrawThemeTextFunc
@@ -171,9 +171,12 @@
            && GetThemeTransitionDurationFunc
           ) {
               DTRACE_PRINTLN("Loaded function pointers.\n");
-              // We need to make sure we can load the Theme. This may not be
-              // the case on a WinXP machine with classic mode enabled.
-              HTHEME hTheme = OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), L"Button");
+              // We need to make sure we can load the Theme.
+              // Use the default DPI value of 96 on windows.
+              constexpr unsigned int defaultDPI = 96;
+              HTHEME hTheme = OpenThemeDataForDpiFunc (
+                              AwtToolkit::GetInstance().GetHWnd(),
+                              L"Button", defaultDPI);
               if(hTheme) {
                   DTRACE_PRINTLN("Loaded Theme data.\n");
                   CloseThemeDataFunc(hTheme);
@@ -236,7 +239,7 @@
  * Signature: (Ljava/lang/String;)J
  */
 JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
-(JNIEnv *env, jclass klass, jstring widget) {
+(JNIEnv *env, jclass klass, jstring widget, jint dpi) {
 
     LPCTSTR str = (LPCTSTR) JNU_GetStringPlatformChars(env, widget, NULL);
     if (str == NULL) {
@@ -245,7 +248,9 @@
     }
     // We need to open the Theme on a Window that will stick around.
     // The best one for that purpose is the Toolkit window.
-    HTHEME htheme = OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
+    HTHEME htheme = OpenThemeDataForDpiFunc(
+                    AwtToolkit::GetInstance().GetHWnd(),
+                    str, dpi);
     JNU_ReleaseStringPlatformChars(env, widget, str);
     return (jlong) htheme;
 }
@@ -378,7 +383,7 @@
  */
 JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
   (JNIEnv *env, jclass klass, jintArray array, jlong theme, jint part, jint state,
-    jint x, jint y, jint w, jint h, jint stride) {
+    jint rectRight, jint rectBottom, jint w, jint h, jint stride) {
 
     int *pDstBits=NULL;
     int *pSrcBits=NULL;
@@ -416,6 +421,7 @@
             NULL, 0);
     if (hDibSection == NULL) {
         DTRACE_PRINTLN("Error creating DIB section");
+        DeleteDC(memDC);
         ReleaseDC(NULL,defaultDC);
         return;
     }
@@ -424,8 +430,8 @@
 
     rect.left = 0;
     rect.top = 0;
-    rect.bottom = h;
-    rect.right = w;
+    rect.bottom = rectBottom;
+    rect.right = rectRight;
 
     ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
 
@@ -714,27 +720,6 @@
     return NULL;
 }
 
-void rescale(SIZE *size) {
-    static int dpiX = -1;
-    static int dpiY = -1;
-    if (dpiX == -1 || dpiY == -1) {
-        HWND hWnd = ::GetDesktopWindow();
-        HDC hDC = ::GetDC(hWnd);
-        dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
-        dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
-        ::ReleaseDC(hWnd, hDC);
-    }
-
-    if (dpiX !=0 && dpiX != 96) {
-        float invScaleX = 96.0f / dpiX;
-        size->cx = (int) round(size->cx * invScaleX);
-    }
-    if (dpiY != 0 && dpiY != 96) {
-        float invScaleY = 96.0f / dpiY;
-        size->cy = (int) round(size->cy * invScaleY);
-    }
-}
-
 /*
  * Class:     sun_awt_windows_ThemeReader
  * Method:    getPartSize
@@ -761,7 +746,6 @@
                 CHECK_NULL_RETURN(dimMID, NULL);
             }
 
-            rescale(&size);
             jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
             if (safe_ExceptionOccurred(env)) {
                 env->ExceptionDescribe();
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp
--- openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	2024-01-16 16:19:00.000000000 +0000
@@ -1790,10 +1790,16 @@
     DWORD dwBytes = sizeof(szFileName);
     // try Typeface-specific EUDC font
     char szTmpName[80];
-    VERIFY(::WideCharToMultiByte(CP_ACP, 0, szFamilyName, -1,
-        szTmpName, sizeof(szTmpName), NULL, NULL));
-    LONG lStatus = ::RegQueryValueExA(hKey, (LPCSTR) szTmpName,
-        NULL, &dwType, szFileName, &dwBytes);
+    int nb = ::WideCharToMultiByte(CP_ACP, 0, szFamilyName, -1,
+        szTmpName, sizeof(szTmpName), NULL, NULL);
+    VERIFY(nb);
+
+    LONG lStatus = 1;
+    if (nb > 0) {
+        lStatus = ::RegQueryValueExA(hKey, (LPCSTR) szTmpName,
+                                     NULL, &dwType, szFileName, &dwBytes);
+    }
+
     BOOL fUseDefault = FALSE;
     if (lStatus != ERROR_SUCCESS){ // try System default EUDC font
         if (m_fTTEUDCFileExist == FALSE)
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp
--- openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2021, 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
@@ -3925,9 +3925,13 @@
                   sizeof(t_errStr),
                   NULL );
 
-    WideCharToMultiByte(CP_UTF8, 0, t_errStr, -1,
+    int nb = WideCharToMultiByte(CP_UTF8, 0, t_errStr, -1,
                         errStr, sizeof(errStr), NULL, NULL);
-    JNU_ThrowByName(env, PRINTEREXCEPTION_STR, errStr);
+    if (nb > 0) {
+        JNU_ThrowByName(env, PRINTEREXCEPTION_STR, errStr);
+    } else {
+        JNU_ThrowByName(env, PRINTEREXCEPTION_STR, "secondary error during OS message extraction");
+    }
 }
 
 
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp
--- openjdk-21-21.0.1+12/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -170,6 +170,8 @@
     // create an offscreen bitmap
     hbitmap = ::CreateCompatibleBitmap(hdcScreen, width, height);
     if (hbitmap == NULL) {
+        ::DeleteDC(hdcMem);
+        ::DeleteDC(hdcScreen);
         throw std::bad_alloc();
     }
     hOldBitmap = (HBITMAP)::SelectObject(hdcMem, hbitmap);
@@ -189,9 +191,21 @@
     static const int BITS_PER_PIXEL = 32;
     static const int BYTES_PER_PIXEL = BITS_PER_PIXEL/8;
 
-    if (!IS_SAFE_SIZE_MUL(width, height)) throw std::bad_alloc();
+    if (!IS_SAFE_SIZE_MUL(width, height)) {
+        ::DeleteObject(hbitmap);
+        ::DeleteDC(hdcMem);
+        ::DeleteDC(hdcScreen);
+        throw std::bad_alloc();
+    }
+
     int numPixels = width*height;
-    if (!IS_SAFE_SIZE_MUL(BYTES_PER_PIXEL, numPixels)) throw std::bad_alloc();
+    if (!IS_SAFE_SIZE_MUL(BYTES_PER_PIXEL, numPixels)) {
+        ::DeleteObject(hbitmap);
+        ::DeleteDC(hdcMem);
+        ::DeleteDC(hdcScreen);
+        throw std::bad_alloc();
+    }
+
     int pixelDataSize = BYTES_PER_PIXEL*numPixels;
     DASSERT(pixelDataSize > 0 && pixelDataSize % 4 == 0);
     // allocate memory for BITMAPINFO + pixel data
@@ -202,6 +216,9 @@
     // See MSDN docs for BITMAPINFOHEADER -bchristi
 
     if (!IS_SAFE_SIZE_ADD(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD), pixelDataSize)) {
+        ::DeleteObject(hbitmap);
+        ::DeleteDC(hdcMem);
+        ::DeleteDC(hdcScreen);
         throw std::bad_alloc();
     }
     BITMAPINFO * pinfo = (BITMAPINFO *)(new BYTE[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD) + pixelDataSize]);
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp openjdk-21-21.0.2+13/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp
--- openjdk-21-21.0.1+12/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -35,16 +35,25 @@
 {
     DWORD dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, nullptr, 0, nullptr, nullptr);
     LPSTR lpUTF8Str = new CHAR[dwUTF8Len];
+    if (lpUTF8Str == NULL) return NULL;
     memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len));
-    WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, nullptr, nullptr);
-    return lpUTF8Str;
+    int nb = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, nullptr, nullptr);
+    if (nb > 0) {
+        return lpUTF8Str;
+    }
+    delete[] lpUTF8Str;
+    return NULL;
 }
 
 void UnicodeToUTF8AndCopy(LPSTR dest, LPCWSTR src, SIZE_T maxLength) {
     LPSTR utf8EncodedName = UnicodeToUTF8(src);
-    strncpy(dest, utf8EncodedName, maxLength - 1);
-    delete[] utf8EncodedName;
-    dest[maxLength - 1] = '\0';
+    if (utf8EncodedName != NULL) {
+        strncpy(dest, utf8EncodedName, maxLength - 1);
+        delete[] utf8EncodedName;
+        dest[maxLength - 1] = '\0';
+    } else {
+        if (maxLength > 0) dest[0] = '\0';
+    }
 }
 
 #ifdef __cplusplus
diff -Nru openjdk-21-21.0.1+12/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp openjdk-21-21.0.2+13/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
--- openjdk-21-21.0.1+12/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
@@ -184,6 +184,12 @@
         return 0;
     }
 
+    HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
+    if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) {
+        DS_unlockCache();
+        return 0;
+    }
+
     if (g_lastCacheRefreshTime == 0
         || (UINT64) timeGetTime() > (UINT64) (g_lastCacheRefreshTime + WAIT_BETWEEN_CACHE_REFRESH_MILLIS)) {
         /* first, initialize any old cache items */
@@ -224,6 +230,11 @@
 
         g_lastCacheRefreshTime = (UINT64) timeGetTime();
     }
+
+    if (hr != RPC_E_CHANGED_MODE) {
+        ::CoUninitialize();
+    }
+
     DS_unlockCache();
     /*TRACE1("DirectSound: %d installed devices\n", g_mixerCount);*/
     return g_mixerCount;
@@ -258,6 +269,13 @@
         DS_unlockCache();
         return FALSE;
     }
+
+    HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
+    if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) {
+        DS_unlockCache();
+        return 0;
+    }
+
     desc->maxSimulLines = 0;
     if (g_audioDeviceCache[desc->deviceID].isSource) {
         DirectSoundEnumerateW((LPDSENUMCALLBACKW) DS_GetDescEnum, desc);
@@ -267,6 +285,10 @@
         strncpy(desc->description, "DirectSound Capture", DAUDIO_STRING_LENGTH);
     }
 
+    if (hr != RPC_E_CHANGED_MODE) {
+        ::CoUninitialize();
+    }
+
     /*desc->vendor;
     desc->version;*/
 
diff -Nru openjdk-21-21.0.1+12/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java openjdk-21-21.0.2+13/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java
--- openjdk-21-21.0.1+12/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	2024-01-16 16:19:00.000000000 +0000
@@ -779,9 +779,13 @@
                 } catch (IllegalArgumentException e) {
                     continue;
                 }
-            } else {
+            } else if (nameObject instanceof String) {
                 issuerName = (String)nameObject;
+            } else {
+                throw new CertStoreException(
+                    "unrecognized issuerName: must be String or byte[]");
             }
+
             // If all we want is CA certs, try to get the (probably shorter) ARL
             Collection entryCRLs = Collections.emptySet();
             if (certChecking == null || certChecking.getBasicConstraints() != -1) {
diff -Nru openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java
--- openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java	2024-01-16 16:19:00.000000000 +0000
@@ -28,8 +28,6 @@
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.UncheckedIOException;
-import java.net.InetSocketAddress;
-import java.net.URI;
 import java.util.Base64;
 import java.util.HashSet;
 import java.util.Map;
@@ -71,7 +69,8 @@
     // only accessed from within lock protected blocks
     private final Set failures = new HashSet<>();
 
-    private final ReentrantLock lock = new ReentrantLock();
+    // used when dealing with connections in the pool
+    private final ReentrantLock connectionPoolLock = new ReentrantLock();
 
     /**
      * When HTTP/2 requested only. The following describes the aggregate behavior including the
@@ -100,15 +99,16 @@
                                                         Exchange exchange) {
         String key = Http2Connection.keyFor(req);
 
-        lock.lock();
+        connectionPoolLock.lock();
         try {
             Http2Connection connection = connections.get(key);
             if (connection != null) {
                 try {
-                    if (!connection.isOpen() || !connection.reserveStream(true)) {
+                    if (!connection.tryReserveForPoolCheckout() || !connection.reserveStream(true)) {
                         if (debug.on())
-                            debug.log("removing found closed or closing connection: %s", connection);
-                        deleteConnection(connection);
+                            debug.log("removing connection from pool since it couldn't be" +
+                                    " reserved for use: %s", connection);
+                        removeFromPool(connection);
                     } else {
                         // fast path if connection already exists
                         if (debug.on())
@@ -128,12 +128,12 @@
                 return MinimalFuture.completedFuture(null);
             }
         } finally {
-            lock.unlock();
+            connectionPoolLock.unlock();
         }
         return Http2Connection
                 .createAsync(req, this, exchange)
                 .whenComplete((conn, t) -> {
-                    lock.lock();
+                    connectionPoolLock.lock();
                     try {
                         if (conn != null) {
                             try {
@@ -148,7 +148,7 @@
                                 failures.add(key);
                         }
                     } finally {
-                        lock.unlock();
+                        connectionPoolLock.unlock();
                     }
                 });
     }
@@ -169,7 +169,7 @@
         }
 
         String key = c.key();
-        lock.lock();
+        connectionPoolLock.lock();
         try {
             if (stopping) {
                 if (debug.on()) debug.log("stopping - closing connection: %s", c);
@@ -192,21 +192,27 @@
                 debug.log("put in the connection pool: %s", c);
             return true;
         } finally {
-            lock.unlock();
+            connectionPoolLock.unlock();
         }
     }
 
-    void deleteConnection(Http2Connection c) {
+    /**
+     * Removes the connection from the pool (if it was in the pool).
+     * This method doesn't close the connection.
+     *
+     * @param c the connection to remove from the pool
+     */
+    void removeFromPool(Http2Connection c) {
         if (debug.on())
             debug.log("removing from the connection pool: %s", c);
-        lock.lock();
+        connectionPoolLock.lock();
         try {
             if (connections.remove(c.key(), c)) {
                 if (debug.on())
                     debug.log("removed from the connection pool: %s", c);
             }
         } finally {
-            lock.unlock();
+            connectionPoolLock.unlock();
         }
     }
 
@@ -215,11 +221,11 @@
         if (debug.on()) debug.log("stopping");
         STOPPED = new EOFException("HTTP/2 client stopped");
         STOPPED.setStackTrace(new StackTraceElement[0]);
-        lock.lock();
+        connectionPoolLock.lock();
         try {
             stopping = true;
         } finally {
-            lock.unlock();
+            connectionPoolLock.unlock();
         }
         do {
             connections.values().forEach(this::close);
diff -Nru openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java
--- openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java	2024-01-16 16:19:00.000000000 +0000
@@ -127,7 +127,8 @@
 
     private static final int MAX_CLIENT_STREAM_ID = Integer.MAX_VALUE; // 2147483647
     private static final int MAX_SERVER_STREAM_ID = Integer.MAX_VALUE - 1; // 2147483646
-    private IdleConnectionTimeoutEvent idleConnectionTimeoutEvent;  // may be null
+    // may be null; must be accessed/updated with the stateLock held
+    private IdleConnectionTimeoutEvent idleConnectionTimeoutEvent;
 
     /**
      * Flag set when no more streams to be opened on this connection.
@@ -192,31 +193,65 @@
     // and has not sent the final stream flag
     final class IdleConnectionTimeoutEvent extends TimeoutEvent {
 
-        private boolean fired;
+        // expected to be accessed/updated with "stateLock" being held
+        private boolean cancelled;
 
         IdleConnectionTimeoutEvent(Duration duration) {
             super(duration);
-            fired = false;
         }
 
+        /**
+         * {@link #shutdown(Throwable) Shuts down} the connection, unless this event is
+         * {@link #cancelled}
+         */
         @Override
         public void handle() {
-            fired = true;
+            // first check if the connection is still idle.
+            // must be done with the "stateLock" held, to allow for synchronizing actions like
+            // closing the connection and checking out from connection pool (which too is expected
+            // to use this same lock)
+            stateLock.lock();
+            try {
+                if (cancelled) {
+                    if (debug.on()) {
+                        debug.log("Not initiating idle connection shutdown");
+                    }
+                    return;
+                }
+                if (!markIdleShutdownInitiated()) {
+                    if (debug.on()) {
+                        debug.log("Unexpected state %s, skipping idle connection shutdown",
+                                describeClosedState(closedState));
+                    }
+                    return;
+                }
+            } finally {
+                stateLock.unlock();
+            }
             if (debug.on()) {
-                debug.log("HTTP connection idle for too long");
+                debug.log("Initiating shutdown of HTTP connection which is idle for too long");
             }
-            HttpConnectTimeoutException hte = new HttpConnectTimeoutException("HTTP connection idle, no active streams. Shutting down.");
+            HttpConnectTimeoutException hte = new HttpConnectTimeoutException(
+                    "HTTP connection idle, no active streams. Shutting down.");
             shutdown(hte);
         }
 
+        /**
+         * Cancels this event. Should be called with stateLock held
+         */
+        void cancel() {
+            assert stateLock.isHeldByCurrentThread() : "Current thread doesn't hold " + stateLock;
+            // mark as cancelled to prevent potentially already triggered event from actually
+            // doing the shutdown
+            this.cancelled = true;
+            // cancel the timer to prevent the event from being triggered (if it hasn't already)
+            client().cancelTimer(this);
+        }
+
         @Override
         public String toString() {
             return "IdleConnectionTimeoutEvent, " + super.toString();
         }
-
-        public boolean isFired() {
-            return fired;
-        }
     }
 
     // A small class that allows to control frames with respect to the state of
@@ -290,8 +325,11 @@
     private static final int HALF_CLOSED_LOCAL  = 1;
     private static final int HALF_CLOSED_REMOTE = 2;
     private static final int SHUTDOWN_REQUESTED = 4;
-    private final Lock stateLock = new ReentrantLock();
-    volatile int closedState;
+    // state when idle connection management initiates a shutdown of the connection, after
+    // which the connection will go into SHUTDOWN_REQUESTED state
+    private static final int IDLE_SHUTDOWN_INITIATED = 8;
+    private final ReentrantLock stateLock = new ReentrantLock();
+    private volatile int closedState;
 
     //-------------------------------------
     final HttpConnection connection;
@@ -492,11 +530,11 @@
         }
         if (clientInitiated && (lastReservedClientStreamid + 2) >= MAX_CLIENT_STREAM_ID) {
             setFinalStream();
-            client2.deleteConnection(this);
+            client2.removeFromPool(this);
             return false;
         } else if (!clientInitiated && (lastReservedServerStreamid + 2) >= MAX_SERVER_STREAM_ID) {
             setFinalStream();
-            client2.deleteConnection(this);
+            client2.removeFromPool(this);
             return false;
         }
         if (clientInitiated)
@@ -766,7 +804,7 @@
         }
         Throwable initialCause = this.cause;
         if (initialCause == null && t != null) this.cause = t;
-        client2.deleteConnection(this);
+        client2.removeFromPool(this);
         for (Stream s : streams.values()) {
             try {
                 s.connectionClosing(t);
@@ -985,8 +1023,7 @@
     }
 
     boolean isOpen() {
-        return !isMarked(closedState, SHUTDOWN_REQUESTED)
-                && connection.channel().isOpen();
+        return !isMarkedForShutdown() && connection.channel().isOpen();
     }
 
     void resetStream(int streamid, int code) {
@@ -1083,10 +1120,11 @@
             // Start timer if property present and not already created
             stateLock.lock();
             try {
-                // idleConnectionTimerEvent is always accessed within a lock protected block
+                // idleConnectionTimeoutEvent is always accessed within a lock protected block
                 if (streams.isEmpty() && idleConnectionTimeoutEvent == null) {
                     idleConnectionTimeoutEvent = client().idleConnectionTimeout()
-                            .map(IdleConnectionTimeoutEvent::new).orElse(null);
+                            .map(IdleConnectionTimeoutEvent::new)
+                            .orElse(null);
                     if (idleConnectionTimeoutEvent != null) {
                         client().registerTimer(idleConnectionTimeoutEvent);
                     }
@@ -1274,23 +1312,53 @@
         return new Stream.PushedStream<>(pg, this, pushEx);
     }
 
+    /**
+     * Attempts to notify the idle connection management that this connection should
+     * be considered "in use". This way the idle connection management doesn't close
+     * this connection during the time the connection is handed out from the pool and any
+     * new stream created on that connection.
+     * @return true if the connection has been successfully reserved and is {@link #isOpen()}. false
+     *          otherwise; in which case the connection must not be handed out from the pool.
+     */
+    boolean tryReserveForPoolCheckout() {
+        // must be done with "stateLock" held to co-ordinate idle connection management
+        stateLock.lock();
+        try {
+            cancelIdleShutdownEvent();
+            // consider the reservation successful only if the connection's state hasn't moved
+            // to "being closed"
+            return isOpen();
+        } finally {
+            stateLock.unlock();
+        }
+    }
+
+    /**
+     * Cancels any event that might have been scheduled to shutdown this connection. Must be called
+     * with the stateLock held.
+     */
+    private void cancelIdleShutdownEvent() {
+        assert stateLock.isHeldByCurrentThread() : "Current thread doesn't hold " + stateLock;
+        if (idleConnectionTimeoutEvent == null) {
+            return;
+        }
+        idleConnectionTimeoutEvent.cancel();
+        idleConnectionTimeoutEvent = null;
+    }
+
      void putStream(Stream stream, int streamid) {
         // increment the reference count on the HttpClientImpl
         // to prevent the SelectorManager thread from exiting until
         // the stream is closed.
         stateLock.lock();
         try {
-            if (!isMarked(closedState, SHUTDOWN_REQUESTED)) {
+            if (!isMarkedForShutdown()) {
                 if (debug.on()) {
                     debug.log("Opened stream %d", streamid);
                 }
                 client().streamReference();
                 streams.put(streamid, stream);
-                // idleConnectionTimerEvent is always accessed within a lock protected block
-                if (idleConnectionTimeoutEvent != null) {
-                    client().cancelTimer(idleConnectionTimeoutEvent);
-                    idleConnectionTimeoutEvent = null;
-                }
+                cancelIdleShutdownEvent();
                 return;
             }
         } finally {
@@ -1653,6 +1721,12 @@
         return (state & mask) == mask;
     }
 
+    private boolean isMarkedForShutdown() {
+        final int closedSt = closedState;
+        return isMarked(closedSt, IDLE_SHUTDOWN_INITIATED)
+                || isMarked(closedSt, SHUTDOWN_REQUESTED);
+    }
+
     private boolean markShutdownRequested() {
         return markClosedState(SHUTDOWN_REQUESTED);
     }
@@ -1665,6 +1739,10 @@
         return markClosedState(HALF_CLOSED_REMOTE);
     }
 
+    private boolean markIdleShutdownInitiated() {
+        return markClosedState(IDLE_SHUTDOWN_INITIATED);
+    }
+
     private boolean markClosedState(int flag) {
         int state, desired;
         do {
@@ -1678,8 +1756,11 @@
     String describeClosedState(int state) {
         if (state == 0) return "active";
         String desc = null;
+        if (isMarked(state, IDLE_SHUTDOWN_INITIATED)) {
+            desc = "idle-shutdown-initiated";
+        }
         if (isMarked(state, SHUTDOWN_REQUESTED)) {
-            desc = "shutdown";
+            desc = desc == null ? "shutdown" : desc + "+shutdown";
         }
         if (isMarked(state, HALF_CLOSED_LOCAL | HALF_CLOSED_REMOTE)) {
             if (desc == null) return "closed";
diff -Nru openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
--- openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java	2024-01-16 16:19:00.000000000 +0000
@@ -622,7 +622,7 @@
                 }
                 closed = true;
             } finally {
-                stateLock.lock();
+                stateLock.unlock();
             }
             try {
                 int error = frame.getErrorCode();
diff -Nru openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java
--- openjdk-21-21.0.1+12/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java	2024-01-16 16:19:00.000000000 +0000
@@ -971,10 +971,12 @@
 
     boolean stopped;
 
-    private synchronized void normalStop() {
-        if (stopped)
-            return;
-        stopped = true;
+    private void normalStop() {
+        synchronized (this) {
+            if (stopped)
+                return;
+            stopped = true;
+        }
         reader.stop();
         writer.stop();
         // make sure the alpnCF is completed.
diff -Nru openjdk-21-21.0.1+12/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c openjdk-21-21.0.2+13/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c
--- openjdk-21-21.0.1+12/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, 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
@@ -71,7 +71,7 @@
     jclass thisclass, jstring java_fname, jint permission, jboolean shared) {
     const char *fname = JNU_GetStringPlatformChars(env, java_fname, NULL);
     int fd, rc;
-    int result[2];
+    int result[2] = {0, 0};
     jintArray javaResult = NULL;
     int old_umask;
     FLOCK fl;
@@ -90,6 +90,7 @@
 
     if (shared == JNI_TRUE) {
         fd = open(fname, O_RDONLY, 0);
+        result[1] = errno;
     } else {
         old_umask = umask(0);
         fd = open(fname, O_WRONLY|O_CREAT, permission);
diff -Nru openjdk-21-21.0.1+12/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java openjdk-21-21.0.2+13/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java
--- openjdk-21-21.0.1+12/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java	2024-01-16 16:19:00.000000000 +0000
@@ -104,6 +104,9 @@
                                         // Full path needed, DLL is in jre/bin
                                         StaticProperty.javaHome() + "\\bin\\sspi_bridge.dll",
                                 };
+                                case AIX -> new String[]{
+                                        "/opt/freeware/lib64/libgssapi_krb5.so",
+                                };
                                 default -> new String[0];
                             };
                         } else {
diff -Nru openjdk-21-21.0.1+12/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java openjdk-21-21.0.2+13/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java
--- openjdk-21-21.0.1+12/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java	2024-01-16 16:19:00.000000000 +0000
@@ -318,7 +318,6 @@
             throw new XMLSignatureException(e);
         }
         LOG.debug("Signature provider: {}", signature.getProvider());
-        LOG.debug("Signing with key: {}", key);
         LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
 
         try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
diff -Nru openjdk-21-21.0.1+12/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java openjdk-21-21.0.2+13/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
--- openjdk-21-21.0.1+12/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	2024-01-16 16:19:00.000000000 +0000
@@ -344,7 +344,6 @@
         }
         signature.initSign((PrivateKey)key);
         LOG.debug("Signature provider: {}", signature.getProvider());
-        LOG.debug("Signing with key: {}", key);
         LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
 
         try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
diff -Nru openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
--- openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	2024-01-16 16:19:00.000000000 +0000
@@ -4712,7 +4712,7 @@
                                          TreeInfo.unguardedCase(testCase);
                         } else if (label instanceof JCPatternCaseLabel patternCL &&
                                    testCaseLabel instanceof JCPatternCaseLabel testPatternCaseLabel &&
-                                   TreeInfo.unguardedCase(testCase)) {
+                                   (testCase.equals(c) || TreeInfo.unguardedCase(testCase))) {
                             dominated = patternDominated(testPatternCaseLabel.pat,
                                                          patternCL.pat);
                         }
diff -Nru openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java
--- openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java	2024-01-16 16:19:00.000000000 +0000
@@ -167,7 +167,7 @@
 
     /** Used to terminate recursion in {@link #invokeInvokable invokeInvokable()}.
      */
-    private final Set>> invocations = new HashSet<>();
+    private final Set>> invocations = new HashSet<>();
 
     /** Snapshot of {@link #callStack} where a possible 'this' escape occurs.
      *  If non-null, a 'this' escape warning has been found in the current
@@ -590,7 +590,7 @@
                 return;
 
             // Stop infinite recursion here
-            Pair> invocation = Pair.of(site, refs.clone());
+            Pair> invocation = Pair.of(methodInfo.declaration, refs.clone());
             if (!invocations.add(invocation))
                 return;
 
@@ -678,7 +678,11 @@
 
     @Override
     public void visitForeachLoop(JCEnhancedForLoop tree) {
-        visitLooped(tree, super::visitForeachLoop);
+        visitLooped(tree, foreach -> {
+            scan(foreach.expr);
+            refs.discardExprs(depth);       // we don't handle iterator() yet
+            scan(foreach.body);
+        });
     }
 
     @Override
@@ -729,7 +733,10 @@
 
     @Override
     public void visitLambda(JCLambda lambda) {
-        visitDeferred(() -> visitScoped(false, () -> super.visitLambda(lambda)));
+        visitDeferred(() -> visitScoped(false, () -> {
+            scan(lambda.body);
+            refs.discardExprs(depth);       // needed in case body is a JCExpression
+        }));
     }
 
     @Override
diff -Nru openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java
--- openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java	2024-01-16 16:19:00.000000000 +0000
@@ -524,6 +524,8 @@
             boolean previousCompletesNormally = false;
             boolean hasDefault = false;
 
+            patchCompletingNormallyCases(cases);
+
             for (var c : cases) {
                 List clearedPatterns = c.labels;
                 boolean hasJoinedNull =
@@ -541,7 +543,8 @@
                     validCaseLabelList = clearedPatterns.head.hasTag(Tag.PATTERNCASELABEL);
                 }
 
-                if (validCaseLabelList && !previousCompletesNormally) {
+                if ((validCaseLabelList && !previousCompletesNormally) ||
+                        c.guard != null) {
                     List labels = clearedPatterns.stream().map(cp -> (JCPatternCaseLabel)cp).collect(List.collector());
                     bindingContext = new BasicBindingContext();
                     VarSymbol prevCurrentValue = currentValue;
@@ -657,6 +660,53 @@
             super.visitSwitchExpression((JCSwitchExpression) tree);
         }
     }
+
+    // Duplicates the block statement where needed.
+    // Processes cases in place, e.g.
+    // switch (obj) {
+    //     case Integer _ when ((Integer) obj) > 0:
+    //     case String _  when !((String) obj).isEmpty():
+    //         return 1;
+    //     ...
+    // }
+    // =>
+    // switch (typeSwitch(...)) {
+    //     case 0:
+    //         if (!((Integer)obj) > 0) { ... }
+    //         return 1;
+    //     case 1:
+    //         if (!((String)obj).isEmpty()) { ... }
+    //         return 1;
+    //     ...
+    // }
+    private static void patchCompletingNormallyCases(List cases) {
+        while (cases.nonEmpty()) {
+            var currentCase = cases.head;
+
+            if (currentCase.caseKind == CaseKind.STATEMENT &&
+                currentCase.completesNormally &&
+                cases.tail.nonEmpty() &&
+                cases.tail.head.guard != null) {
+                ListBuffer newStatements = new ListBuffer<>();
+                List copyFrom = cases;
+
+                while (copyFrom.nonEmpty()) {
+                    newStatements.appendList(copyFrom.head.stats);
+
+                    if (!copyFrom.head.completesNormally) {
+                        break;
+                    }
+
+                    copyFrom = copyFrom.tail;
+                };
+
+                currentCase.stats = newStatements.toList();
+            }
+
+            cases = cases.tail;
+        }
+    }
+
     //where:
         private void fixupContinue(JCTree switchTree, JCCase c, VarSymbol indexVariable, int currentCaseIndex) {
             //inject 'index = currentCaseIndex + 1;` before continue which has the current switch as the target
diff -Nru openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
--- openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	2024-01-16 16:19:00.000000000 +0000
@@ -1278,11 +1278,17 @@
     }
     //where:
         private boolean hasTry(JCSwitchExpression tree) {
-            boolean[] hasTry = new boolean[1];
-            new TreeScanner() {
+            class HasTryScanner extends TreeScanner {
+                private boolean hasTry;
+
                 @Override
                 public void visitTry(JCTry tree) {
-                    hasTry[0] = true;
+                    hasTry = true;
+                }
+
+                @Override
+                public void visitSynchronized(JCSynchronized tree) {
+                    hasTry = true;
                 }
 
                 @Override
@@ -1292,8 +1298,12 @@
                 @Override
                 public void visitLambda(JCLambda tree) {
                 }
-            }.scan(tree);
-            return hasTry[0];
+            };
+
+            HasTryScanner hasTryScanner = new HasTryScanner();
+
+            hasTryScanner.scan(tree);
+            return hasTryScanner.hasTry;
         }
 
     private void handleSwitch(JCTree swtch, JCExpression selector, List cases,
diff -Nru openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
--- openjdk-21-21.0.1+12/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	2024-01-16 16:19:00.000000000 +0000
@@ -3918,7 +3918,7 @@
 
         boolean firstTypeDecl = true;   // have we see a class, enum, or interface declaration yet?
         boolean isUnnamedClass = false;
-        while (token.kind != EOF) {
+        OUTER: while (token.kind != EOF) {
             if (token.pos <= endPosTable.errorEndPos) {
                 // error recovery
                 skip(firstTypeDecl, false, false, false);
@@ -3933,6 +3933,8 @@
             while (firstTypeDecl && mods == null && token.kind == SEMI) {
                 semiList.append(toP(F.at(token.pos).Skip()));
                 nextToken();
+                if (token.kind == EOF)
+                    break OUTER;
             }
             if (firstTypeDecl && mods == null && token.kind == IMPORT) {
                 if (!semiList.isEmpty()) {
@@ -3999,7 +4001,7 @@
                     checkSourceLevel(token.pos, Feature.UNNAMED_CLASSES);
                     defs.appendList(topLevelMethodOrFieldDeclaration(mods));
                     isUnnamedClass = true;
-                } else if (token.kind != EOF) {
+                } else {
                     JCTree def = typeDeclaration(mods, docComment);
                     if (def instanceof JCExpressionStatement statement)
                         def = statement.expr;
diff -Nru openjdk-21-21.0.1+12/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CRSACipher.java openjdk-21-21.0.2+13/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CRSACipher.java
--- openjdk-21-21.0.1+12/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CRSACipher.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CRSACipher.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2021, 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
@@ -30,6 +30,7 @@
 import java.security.Key;
 import java.security.interfaces.*;
 import java.security.spec.*;
+import java.util.Arrays;
 
 import javax.crypto.*;
 import javax.crypto.spec.*;
@@ -61,6 +62,9 @@
  */
 public final class CRSACipher extends CipherSpi {
 
+    private static final int ERROR_INVALID_PARAMETER = 0x57;
+    private static final int NTE_INVALID_PARAMETER = 0x80090027;
+
     // constant for an empty byte array
     private static final byte[] B0 = new byte[0];
 
@@ -101,6 +105,8 @@
     // cipher parameter for TLS RSA premaster secret
     private AlgorithmParameterSpec spec = null;
 
+    private boolean forTlsPremasterSecret = false;
+
     // the source of randomness
     private SecureRandom random;
 
@@ -171,6 +177,9 @@
             }
             spec = params;
             this.random = random;   // for TLS RSA premaster secret
+            this.forTlsPremasterSecret = true;
+        } else {
+            this.forTlsPremasterSecret = false;
         }
         init(opmode, key);
     }
@@ -278,8 +287,7 @@
     }
 
     // internal doFinal() method. Here we perform the actual RSA operation
-    private byte[] doFinal() throws BadPaddingException,
-            IllegalBlockSizeException {
+    private byte[] doFinal() throws IllegalBlockSizeException {
         if (bufOfs > buffer.length) {
             throw new IllegalBlockSizeException("Data must not be longer "
                 + "than " + (buffer.length - paddingLength)  + " bytes");
@@ -308,7 +316,7 @@
                 throw new AssertionError("Internal error");
             }
 
-        } catch (KeyException e) {
+        } catch (KeyException | BadPaddingException e) {
             throw new ProviderException(e);
 
         } finally {
@@ -331,14 +339,14 @@
 
     // see JCE spec
     protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
-            throws BadPaddingException, IllegalBlockSizeException {
+            throws IllegalBlockSizeException {
         update(in, inOfs, inLen);
         return doFinal();
     }
 
     // see JCE spec
     protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
-            int outOfs) throws ShortBufferException, BadPaddingException,
+            int outOfs) throws ShortBufferException,
             IllegalBlockSizeException {
         if (outputSize > out.length - outOfs) {
             throw new ShortBufferException
@@ -354,6 +362,7 @@
     // see JCE spec
     protected byte[] engineWrap(Key key) throws InvalidKeyException,
             IllegalBlockSizeException {
+
         byte[] encoded = key.getEncoded(); // TODO - unextractable key
         if ((encoded == null) || (encoded.length == 0)) {
             throw new InvalidKeyException("Could not obtain encoded key");
@@ -362,12 +371,7 @@
             throw new InvalidKeyException("Key is too long for wrapping");
         }
         update(encoded, 0, encoded.length);
-        try {
-            return doFinal();
-        } catch (BadPaddingException e) {
-            // should not occur
-            throw new InvalidKeyException("Wrapping failed", e);
-        }
+        return doFinal();
     }
 
     // see JCE spec
@@ -388,31 +392,31 @@
         update(wrappedKey, 0, wrappedKey.length);
         try {
             encoded = doFinal();
-        } catch (BadPaddingException e) {
-            if (isTlsRsaPremasterSecret) {
-                failover = e;
-            } else {
-                throw new InvalidKeyException("Unwrapping failed", e);
-            }
         } catch (IllegalBlockSizeException e) {
             // should not occur, handled with length check above
             throw new InvalidKeyException("Unwrapping failed", e);
         }
 
-        if (isTlsRsaPremasterSecret) {
-            if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
-                throw new IllegalStateException(
-                        "No TlsRsaPremasterSecretParameterSpec specified");
+        try {
+            if (isTlsRsaPremasterSecret) {
+                if (!forTlsPremasterSecret) {
+                    throw new IllegalStateException(
+                            "No TlsRsaPremasterSecretParameterSpec specified");
+                }
+
+                // polish the TLS premaster secret
+                encoded = KeyUtil.checkTlsPreMasterSecretKey(
+                        ((TlsRsaPremasterSecretParameterSpec) spec).getClientVersion(),
+                        ((TlsRsaPremasterSecretParameterSpec) spec).getServerVersion(),
+                        random, encoded, encoded == null);
             }
 
-            // polish the TLS premaster secret
-            encoded = KeyUtil.checkTlsPreMasterSecretKey(
-                ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
-                ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
-                random, encoded, (failover != null));
+            return constructKey(encoded, algorithm, type);
+        } finally {
+            if (encoded != null) {
+                Arrays.fill(encoded, (byte) 0);
+            }
         }
-
-        return constructKey(encoded, algorithm, type);
     }
 
     // see JCE spec
@@ -496,17 +500,30 @@
      * Encrypt/decrypt a data buffer using Microsoft Crypto API or CNG.
      * It expects and returns ciphertext data in big-endian form.
      */
-    private static byte[] encryptDecrypt(byte[] data, int dataSize,
-            CKey key, boolean doEncrypt) throws KeyException {
+    private byte[] encryptDecrypt(byte[] data, int dataSize,
+            CKey key, boolean doEncrypt) throws KeyException, BadPaddingException {
+        int[] returnStatus = new int[1];
+        byte[] result;
         if (key.getHCryptKey() != 0) {
-            return encryptDecrypt(data, dataSize, key.getHCryptKey(), doEncrypt);
+            result = encryptDecrypt(returnStatus, data, dataSize, key.getHCryptKey(), doEncrypt);
         } else {
-            return cngEncryptDecrypt(data, dataSize, key.getHCryptProvider(), doEncrypt);
+            result = cngEncryptDecrypt(returnStatus, data, dataSize, key.getHCryptProvider(), doEncrypt);
         }
+        if ((returnStatus[0] == ERROR_INVALID_PARAMETER) || (returnStatus[0] == NTE_INVALID_PARAMETER)) {
+            if (forTlsPremasterSecret) {
+                result = null;
+            } else {
+                throw new BadPaddingException("Error " + returnStatus[0] + " returned by MSCAPI");
+            }
+        } else if (returnStatus[0] != 0) {
+            throw new KeyException("Error " + returnStatus[0] + " returned by MSCAPI");
+        }
+
+        return result;
     }
 
-    private static native byte[] encryptDecrypt(byte[] data, int dataSize,
+    private static native byte[] encryptDecrypt(int[] returnStatus, byte[] data, int dataSize,
             long key, boolean doEncrypt) throws KeyException;
-    private static native byte[] cngEncryptDecrypt(byte[] data, int dataSize,
+    private static native byte[] cngEncryptDecrypt(int[] returnStatus, byte[] data, int dataSize,
             long key, boolean doEncrypt) throws KeyException;
 }
diff -Nru openjdk-21-21.0.1+12/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp openjdk-21-21.0.2+13/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp
--- openjdk-21-21.0.1+12/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp	2024-01-16 16:19:00.000000000 +0000
@@ -1900,18 +1900,25 @@
 /*
  * Class:     sun_security_mscapi_CRSACipher
  * Method:    encryptDecrypt
- * Signature: ([BIJZ)[B
+ * Signature: ([I[BIJZ)[B
  */
 JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CRSACipher_encryptDecrypt
-  (JNIEnv *env, jclass clazz, jbyteArray jData, jint jDataSize, jlong hKey,
+  (JNIEnv *env, jclass clazz, jintArray jResultStatus, jbyteArray jData, jint jDataSize, jlong hKey,
    jboolean doEncrypt)
 {
     jbyteArray result = NULL;
     jbyte* pData = NULL;
+    jbyte* resultData = NULL;
     DWORD dwDataLen = jDataSize;
     DWORD dwBufLen = env->GetArrayLength(jData);
     DWORD i;
     BYTE tmp;
+    BOOL success;
+    DWORD ss = ERROR_SUCCESS;
+    DWORD lastError = ERROR_SUCCESS;
+    DWORD resultLen = 0;
+    DWORD pmsLen = 48;
+    jbyte pmsArr[48] = {0};
 
     __try
     {
@@ -1938,6 +1945,8 @@
                 pData[i] = pData[dwBufLen - i -1];
                 pData[dwBufLen - i - 1] = tmp;
             }
+            resultData = pData;
+            resultLen = dwBufLen;
         } else {
             // convert to little-endian
             for (i = 0; i < dwBufLen / 2; i++) {
@@ -1947,21 +1956,28 @@
             }
 
             // decrypt
-            if (! ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
-                &dwBufLen)) {
-
-                ThrowException(env, KEY_EXCEPTION, GetLastError());
-                __leave;
+            success = ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
+                &dwBufLen);
+            lastError = GetLastError();
+            if (success) {
+                ss = ERROR_SUCCESS;
+                resultData = pData;
+                resultLen = dwBufLen;
+            } else {
+                ss = lastError;
+                resultData = pmsArr;
+                resultLen = pmsLen;
             }
+            env->SetIntArrayRegion(jResultStatus, 0, 1, (jint*) &ss);
         }
 
-        // Create new byte array
-        if ((result = env->NewByteArray(dwBufLen)) == NULL) {
+            // Create new byte array
+        if ((result = env->NewByteArray(resultLen)) == NULL) {
             __leave;
         }
 
         // Copy data from native buffer to Java buffer
-        env->SetByteArrayRegion(result, 0, dwBufLen, (jbyte*) pData);
+        env->SetByteArrayRegion(result, 0, resultLen, (jbyte*) resultData);
     }
     __finally
     {
@@ -1975,17 +1991,22 @@
 /*
  * Class:     sun_security_mscapi_CRSACipher
  * Method:    cngEncryptDecrypt
- * Signature: ([BIJZ)[B
+ * Signature: ([I[BIJZ)[B
  */
 JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CRSACipher_cngEncryptDecrypt
-  (JNIEnv *env, jclass clazz, jbyteArray jData, jint jDataSize, jlong hKey,
+  (JNIEnv *env, jclass clazz, jintArray jResultStatus, jbyteArray jData, jint jDataSize, jlong hKey,
    jboolean doEncrypt)
 {
     SECURITY_STATUS ss;
     jbyteArray result = NULL;
     jbyte* pData = NULL;
+    jbyte* resultData = NULL;
     DWORD dwDataLen = jDataSize;
     DWORD dwBufLen = env->GetArrayLength(jData);
+    DWORD resultLen = 0;
+    DWORD pmsLen = 48;
+    jbyte pmsArr[48] = {0};
+
     __try
     {
         // Copy data from Java buffer to native buffer
@@ -2005,6 +2026,9 @@
             if (ss != ERROR_SUCCESS) {
                 ThrowException(env, KEY_EXCEPTION, ss);
                 __leave;
+            } else {
+                resultLen = dwBufLen;
+                resultData = pData;
             }
         } else {
             // decrypt
@@ -2013,18 +2037,22 @@
                     0,
                     (PBYTE)pData, dwBufLen,
                     &dwBufLen, NCRYPT_PAD_PKCS1_FLAG);
-            if (ss != ERROR_SUCCESS) {
-                ThrowException(env, KEY_EXCEPTION, ss);
-                __leave;
+            env->SetIntArrayRegion(jResultStatus, 0, 1, (jint*) &ss);
+            if (ss == ERROR_SUCCESS) {
+                resultLen = dwBufLen;
+                resultData = pData;
+            } else {
+                resultLen = pmsLen;
+                resultData = pmsArr;
             }
-        }
+       }
         // Create new byte array
-        if ((result = env->NewByteArray(dwBufLen)) == NULL) {
+        if ((result = env->NewByteArray(resultLen)) == NULL) {
             __leave;
         }
 
         // Copy data from native buffer to Java buffer
-        env->SetByteArrayRegion(result, 0, dwBufLen, (jbyte*) pData);
+        env->SetByteArrayRegion(result, 0, resultLen, (jbyte*) resultData);
     }
     __finally {
         if (pData) {
diff -Nru openjdk-21-21.0.1+12/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java openjdk-21-21.0.2+13/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java
--- openjdk-21-21.0.1+12/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	2024-01-16 16:19:00.000000000 +0000
@@ -238,7 +238,11 @@
                         return thread;
                      }
                 }
-                throw new InternalError("We should have found a thread that owns the anonymous lock");
+                // We should have found the owner, however, as the VM could be in any state, including the middle
+                // of performing GC, it is not always possible to do so. Just return null if we can't locate it.
+                System.out.println("Warning: We failed to find a thread that owns an anonymous lock. This is likely");
+                System.out.println("due to the JVM currently running a GC. Locking information may not be accurate.");
+                return null;
             }
             // Owner can only be threads at this point.
             Address o = monitor.owner();
diff -Nru openjdk-21-21.0.1+12/src/jdk.internal.le/share/legal/jline.md openjdk-21-21.0.2+13/src/jdk.internal.le/share/legal/jline.md
--- openjdk-21-21.0.1+12/src/jdk.internal.le/share/legal/jline.md	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/src/jdk.internal.le/share/legal/jline.md	2024-01-16 16:19:00.000000000 +0000
@@ -38,257 +38,4 @@
 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
-4th Party Dependency
-=============
-org.fusesource.jansi version 2.4.0
-org.apache.sshd 2.9.2
-org.apache.felix.gogo.runtime 1.1.6
-org.apache.felix.gogo.jline 1.1.8
-=============
-Apache License
-                          Version 2.0, January 2004
-                       http://www.apache.org/licenses/
-
-  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-  1. Definitions.
-
-     "License" shall mean the terms and conditions for use, reproduction,
-     and distribution as defined by Sections 1 through 9 of this document.
-
-     "Licensor" shall mean the copyright owner or entity authorized by
-     the copyright owner that is granting the License.
-
-     "Legal Entity" shall mean the union of the acting entity and all
-     other entities that control, are controlled by, or are under common
-     control with that entity. For the purposes of this definition,
-     "control" means (i) the power, direct or indirect, to cause the
-     direction or management of such entity, whether by contract or
-     otherwise, or (ii) ownership of fifty percent (50%) or more of the
-     outstanding shares, or (iii) beneficial ownership of such entity.
-
-     "You" (or "Your") shall mean an individual or Legal Entity
-     exercising permissions granted by this License.
-
-     "Source" form shall mean the preferred form for making modifications,
-     including but not limited to software source code, documentation
-     source, and configuration files.
-
-     "Object" form shall mean any form resulting from mechanical
-     transformation or translation of a Source form, including but
-     not limited to compiled object code, generated documentation,
-     and conversions to other media types.
-
-     "Work" shall mean the work of authorship, whether in Source or
-     Object form, made available under the License, as indicated by a
-     copyright notice that is included in or attached to the work
-     (an example is provided in the Appendix below).
-
-     "Derivative Works" shall mean any work, whether in Source or Object
-     form, that is based on (or derived from) the Work and for which the
-     editorial revisions, annotations, elaborations, or other modifications
-     represent, as a whole, an original work of authorship. For the purposes
-     of this License, Derivative Works shall not include works that remain
-     separable from, or merely link (or bind by name) to the interfaces of,
-     the Work and Derivative Works thereof.
-
-     "Contribution" shall mean any work of authorship, including
-     the original version of the Work and any modifications or additions
-     to that Work or Derivative Works thereof, that is intentionally
-     submitted to Licensor for inclusion in the Work by the copyright owner
-     or by an individual or Legal Entity authorized to submit on behalf of
-     the copyright owner. For the purposes of this definition, "submitted"
-     means any form of electronic, verbal, or written communication sent
-     to the Licensor or its representatives, including but not limited to
-     communication on electronic mailing lists, source code control systems,
-     and issue tracking systems that are managed by, or on behalf of, the
-     Licensor for the purpose of discussing and improving the Work, but
-     excluding communication that is conspicuously marked or otherwise
-     designated in writing by the copyright owner as "Not a Contribution."
-
-     "Contributor" shall mean Licensor and any individual or Legal Entity
-     on behalf of whom a Contribution has been received by Licensor and
-     subsequently incorporated within the Work.
-
-  2. Grant of Copyright License. Subject to the terms and conditions of
-     this License, each Contributor hereby grants to You a perpetual,
-     worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-     copyright license to reproduce, prepare Derivative Works of,
-     publicly display, publicly perform, sublicense, and distribute the
-     Work and such Derivative Works in Source or Object form.
-
-  3. Grant of Patent License. Subject to the terms and conditions of
-     this License, each Contributor hereby grants to You a perpetual,
-     worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-     (except as stated in this section) patent license to make, have made,
-     use, offer to sell, sell, import, and otherwise transfer the Work,
-     where such license applies only to those patent claims licensable
-     by such Contributor that are necessarily infringed by their
-     Contribution(s) alone or by combination of their Contribution(s)
-     with the Work to which such Contribution(s) was submitted. If You
-     institute patent litigation against any entity (including a
-     cross-claim or counterclaim in a lawsuit) alleging that the Work
-     or a Contribution incorporated within the Work constitutes direct
-     or contributory patent infringement, then any patent licenses
-     granted to You under this License for that Work shall terminate
-     as of the date such litigation is filed.
-
-  4. Redistribution. You may reproduce and distribute copies of the
-     Work or Derivative Works thereof in any medium, with or without
-     modifications, and in Source or Object form, provided that You
-     meet the following conditions:
-
-     (a) You must give any other recipients of the Work or
-         Derivative Works a copy of this License; and
-
-     (b) You must cause any modified files to carry prominent notices
-         stating that You changed the files; and
-
-     (c) You must retain, in the Source form of any Derivative Works
-         that You distribute, all copyright, patent, trademark, and
-         attribution notices from the Source form of the Work,
-         excluding those notices that do not pertain to any part of
-         the Derivative Works; and
-
-     (d) If the Work includes a "NOTICE" text file as part of its
-         distribution, then any Derivative Works that You distribute must
-         include a readable copy of the attribution notices contained
-         within such NOTICE file, excluding those notices that do not
-         pertain to any part of the Derivative Works, in at least one
-         of the following places: within a NOTICE text file distributed
-         as part of the Derivative Works; within the Source form or
-         documentation, if provided along with the Derivative Works; or,
-         within a display generated by the Derivative Works, if and
-         wherever such third-party notices normally appear. The contents
-         of the NOTICE file are for informational purposes only and
-         do not modify the License. You may add Your own attribution
-         notices within Derivative Works that You distribute, alongside
-         or as an addendum to the NOTICE text from the Work, provided
-         that such additional attribution notices cannot be construed
-         as modifying the License.
-
-     You may add Your own copyright statement to Your modifications and
-     may provide additional or different license terms and conditions
-     for use, reproduction, or distribution of Your modifications, or
-     for any such Derivative Works as a whole, provided Your use,
-     reproduction, and distribution of the Work otherwise complies with
-     the conditions stated in this License.
-
-  5. Submission of Contributions. Unless You explicitly state otherwise,
-     any Contribution intentionally submitted for inclusion in the Work
-     by You to the Licensor shall be under the terms and conditions of
-     this License, without any additional terms or conditions.
-     Notwithstanding the above, nothing herein shall supersede or modify
-     the terms of any separate license agreement you may have executed
-     with Licensor regarding such Contributions.
-
-  6. Trademarks. This License does not grant permission to use the trade
-     names, trademarks, service marks, or product names of the Licensor,
-     except as required for reasonable and customary use in describing the
-     origin of the Work and reproducing the content of the NOTICE file.
-
-  7. Disclaimer of Warranty. Unless required by applicable law or
-     agreed to in writing, Licensor provides the Work (and each
-     Contributor provides its Contributions) on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-     implied, including, without limitation, any warranties or conditions
-     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-     PARTICULAR PURPOSE. You are solely responsible for determining the
-     appropriateness of using or redistributing the Work and assume any
-     risks associated with Your exercise of permissions under this License.
-
-  8. Limitation of Liability. In no event and under no legal theory,
-     whether in tort (including negligence), contract, or otherwise,
-     unless required by applicable law (such as deliberate and grossly
-     negligent acts) or agreed to in writing, shall any Contributor be
-     liable to You for damages, including any direct, indirect, special,
-     incidental, or consequential damages of any character arising as a
-     result of this License or out of the use or inability to use the
-     Work (including but not limited to damages for loss of goodwill,
-     work stoppage, computer failure or malfunction, or any and all
-     other commercial damages or losses), even if such Contributor
-     has been advised of the possibility of such damages.
-
-  9. Accepting Warranty or Additional Liability. While redistributing
-     the Work or Derivative Works thereof, You may choose to offer,
-     and charge a fee for, acceptance of support, warranty, indemnity,
-     or other liability obligations and/or rights consistent with this
-     License. However, in accepting such obligations, You may act only
-     on Your own behalf and on Your sole responsibility, not on behalf
-     of any other Contributor, and only if You agree to indemnify,
-     defend, and hold each Contributor harmless for any liability
-     incurred by, or claims asserted against, such Contributor by reason
-     of your accepting any such warranty or additional liability.
-
-  END OF TERMS AND CONDITIONS
-
-  APPENDIX: How to apply the Apache License to your work.
-
-     To apply the Apache License to your work, attach the following
-     boilerplate notice, with the fields enclosed by brackets "[]"
-     replaced with your own identifying information. (Don't include
-     the brackets!)  The text should be enclosed in the appropriate
-     comment syntax for the file format. We also recommend that a
-     file or class name and description of purpose be included on the
-     same "printed page" as the copyright notice for easier
-     identification within third-party archives.
-
-  Copyright [yyyy] [name of copyright owner]
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-
-=============
-juniversalchardet
-
-The library is subject to the Mozilla Public License Version 1.1.
-
-Alternatively, the library may be used under the terms of either the GNU General Public License Version 2 or later, or the GNU Lesser General Public License 2.1 or later.
-
-================
-
-slf4j
-
-SLF4J source code and binaries are distributed under the MIT license.
-
-
-Copyright (c) 2004-2023 QOS.ch
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY,   FITNESS   FOR   A  PARTICULAR   PURPOSE   AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-These terms are identical to those of the MIT License, also called the X License
-or the X11 License, which is a simple, permissive non-copyleft free software license.
-It is deemed compatible with virtually all types of licenses, commercial or otherwise.
-In particular, the Free Software Foundation has declared it compatible with GNU GPL.
-It is also known to be approved by the Apache Software Foundation as compatible with
-Apache Software License.
-
 
diff -Nru openjdk-21-21.0.1+12/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java openjdk-21-21.0.2+13/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java --- openjdk-21-21.0.1+12/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -264,9 +264,11 @@ StyledText externalSnippet = null; try { - Diags d = (text, pos) -> { + Diags d = (key, pos) -> { var path = writer.configuration().utils.getCommentHelper(holder) .getDocTreePath(snippetTag.getBody()); + var resources = writer.configuration().getDocResources(); + var text = resources.getText(key); writer.configuration().getReporter().print(Diagnostic.Kind.WARNING, path, pos, pos, pos, text); }; @@ -286,7 +288,7 @@ try { var finalFileObject = fileObject; - Diags d = (text, pos) -> writer.configuration().getMessages().warning(finalFileObject, pos, pos, pos, text); + Diags d = (key, pos) -> writer.configuration().getMessages().warning(finalFileObject, pos, pos, pos, key); if (externalContent != null) { externalSnippet = parse(writer.configuration().getDocResources(), d, language, externalContent); } @@ -373,7 +375,7 @@ } public interface Diags { - void warn(String text, int pos); + void warn(String key, int pos); } private static String stringValueOf(AttributeTree at) throws BadSnippetException { diff -Nru openjdk-21-21.0.1+12/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java openjdk-21-21.0.2+13/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java --- openjdk-21-21.0.1+12/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -161,7 +161,7 @@ } } if (parsedTags.isEmpty()) { // (2) - diags.warn(resources.getText("doclet.snippet.markup.spurious"), next.offset() + markedUpLine.start("markup")); + diags.warn("doclet.snippet.markup.spurious", next.offset() + markedUpLine.start("markup")); line = rawLine + (addLineTerminator ? "\n" : ""); } else { // (3) hasMarkup = true; diff -Nru openjdk-21-21.0.1+12/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c openjdk-21-21.0.2+13/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c --- openjdk-21-21.0.1+12/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c 2024-01-16 16:19:00.000000000 +0000 @@ -102,7 +102,7 @@ static void JNICALL cbEarlyException(jvmtiEnv*, JNIEnv *, jthread, jmethodID, jlocation, jobject, jmethodID, jlocation); -static void initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei); +static void initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei, EventInfo *opt_info); static jboolean parseOptions(char *str); /* @@ -391,7 +391,7 @@ EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at VM_INIT time"); } if (initOnStartup) - initialize(env, thread, EI_VM_INIT); + initialize(env, thread, EI_VM_INIT, NULL); vmInitialized = JNI_TRUE; LOG_MISC(("END cbEarlyVMInit")); } @@ -444,6 +444,19 @@ LOG_MISC(("VM is not initialized yet")); return; } + EventInfo info; + info.ei = EI_EXCEPTION; + info.thread = thread; + info.clazz = getMethodClass(jvmti_env, method); + info.method = method; + info.location = location; + info.object = exception; + if (gdata->vthreadsSupported) { + info.is_vthread = isVThread(thread); + } + info.u.exception.catch_clazz = getMethodClass(jvmti_env, catch_method); + info.u.exception.catch_method = catch_method; + info.u.exception.catch_location = catch_location; /* * We want to preserve any current exception that might get wiped @@ -458,24 +471,22 @@ if (initOnUncaught && catch_method == NULL) { LOG_MISC(("Initializing on uncaught exception")); - initialize(env, thread, EI_EXCEPTION); + initialize(env, thread, EI_EXCEPTION, &info); } else if (initOnException != NULL) { - jclass clazz; - - /* Get class of exception thrown */ - clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, exception); - if ( clazz != NULL ) { + jclass exception_clazz = JNI_FUNC_PTR(env, GetObjectClass)(env, exception); + /* check class of exception thrown */ + if ( exception_clazz != NULL ) { char *signature = NULL; /* initing on throw, check */ - error = classSignature(clazz, &signature, NULL); + error = classSignature(exception_clazz, &signature, NULL); LOG_MISC(("Checking specific exception: looking for %s, got %s", initOnException, signature)); if ( (error==JVMTI_ERROR_NONE) && (strcmp(signature, initOnException) == 0)) { LOG_MISC(("Initializing on specific exception")); - initialize(env, thread, EI_EXCEPTION); + initialize(env, thread, EI_EXCEPTION, &info); } else { error = AGENT_ERROR_INTERNAL; /* Just to cause restore */ } @@ -616,9 +627,11 @@ /* * Initialize debugger back end modules + * + * @param opt_info optional event info to use, might be null */ static void -initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei) +initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei, EventInfo *opt_info) { jvmtiError error; EnumerateArg arg; @@ -706,13 +719,13 @@ * can get in the queue (from other not-yet-suspended threads) * before this one does. (Also need to handle allocation error below?) */ - EventInfo info; struct bag *initEventBag; - LOG_MISC(("triggering_ei != EI_VM_INIT")); + LOG_MISC(("triggering_ei == EI_EXCEPTION")); + JDI_ASSERT(triggering_ei == EI_EXCEPTION); + JDI_ASSERT(opt_info != NULL); initEventBag = eventHelper_createEventBag(); - (void)memset(&info,0,sizeof(info)); - info.ei = triggering_ei; - eventHelper_recordEvent(&info, 0, suspendPolicy, initEventBag); + threadControl_onEventHandlerEntry(currentSessionID, opt_info, NULL); + eventHelper_recordEvent(opt_info, 0, suspendPolicy, initEventBag); (void)eventHelper_reportEvents(currentSessionID, initEventBag); bagDestroyBag(initEventBag); } @@ -822,6 +835,9 @@ "transport= transport spec none\n" "address= transport spec \"\"\n" "server=y|n listen for debugger? n\n" + "allow= If server=y, allows connections only from the IP addresses/subnets specified.\n" + " A list of multiple IP address/subnet entries must be separated by \'+\'.\n" + " * (allows connection from any address)\n" "launch= run debugger on event none\n" "onthrow= debug on throw none\n" "onuncaught=y|n debug on any uncaught? n\n" @@ -1368,7 +1384,7 @@ if (!startedViaJcmd) { startedViaJcmd = JNI_TRUE; is_first_start = JNI_TRUE; - initialize(env, thread, EI_VM_INIT); + initialize(env, thread, EI_VM_INIT, NULL); } bagEnumerateOver(transports, getFirstTransport, &spec); diff -Nru openjdk-21-21.0.1+12/src/jdk.jfr/share/conf/jfr/default.jfc openjdk-21-21.0.2+13/src/jdk.jfr/share/conf/jfr/default.jfc --- openjdk-21-21.0.1+12/src/jdk.jfr/share/conf/jfr/default.jfc 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jfr/share/conf/jfr/default.jfc 2024-01-16 16:19:00.000000000 +0000 @@ -735,8 +735,8 @@ - false - true + false + true @@ -745,13 +745,13 @@ - false - true + false + true - false - true + false + true @@ -760,13 +760,13 @@ - false - true + false + true - false - true + false + true @@ -921,15 +921,13 @@ - - - + @@ -974,7 +972,7 @@ - + @@ -1122,7 +1120,6 @@ 20 ms false - diff -Nru openjdk-21-21.0.1+12/src/jdk.jfr/share/conf/jfr/profile.jfc openjdk-21-21.0.2+13/src/jdk.jfr/share/conf/jfr/profile.jfc --- openjdk-21-21.0.1+12/src/jdk.jfr/share/conf/jfr/profile.jfc 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jfr/share/conf/jfr/profile.jfc 2024-01-16 16:19:00.000000000 +0000 @@ -735,8 +735,8 @@ - false - true + false + true @@ -745,13 +745,13 @@ - false - true + false + true - false - true + false + true @@ -760,13 +760,13 @@ - false - true + false + true - false - true + false + true @@ -927,7 +927,7 @@ carry the control attribute. --> - + @@ -945,11 +945,11 @@ - + - + @@ -967,7 +967,7 @@ - + @@ -1120,7 +1120,6 @@ 10 ms false - diff -Nru openjdk-21-21.0.1+12/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java openjdk-21-21.0.2+13/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java --- openjdk-21-21.0.1+12/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java 2024-01-16 16:19:00.000000000 +0000 @@ -52,7 +52,6 @@ archName = platformString.substring(index + 1); // Alias architecture names, if needed archName = archName.replace("amd64", "X64"); - archName = archName.replace("ppc64le", "PPC64"); archName = archName.replace("s390x", "S390"); Architecture arch = Architecture.valueOf(archName.toUpperCase(Locale.ROOT)); diff -Nru openjdk-21-21.0.1+12/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java openjdk-21-21.0.2+13/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java --- openjdk-21-21.0.1+12/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java 2024-01-16 16:19:00.000000000 +0000 @@ -146,7 +146,7 @@ if (split.length != 2) { throw new IllegalArgumentException(getName() + ": " + arg); } - if (split[0].equals("batch-size")) { + if (!split[0].equals("batch-size")) { throw new IllegalArgumentException(getName() + ": " + arg); } this.moduleDescriptorsPerMethod = Integer.parseInt(split[1]); diff -Nru openjdk-21-21.0.1+12/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec openjdk-21-21.0.2+13/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec --- openjdk-21-21.0.1+12/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec 2024-01-16 16:19:00.000000000 +0000 @@ -30,9 +30,12 @@ #build time will substantially increase and it may require unpack200/system java to install %define __jar_repack %{nil} -%define package_filelist %{_tmppath}/%{name}.files -%define app_filelist %{_tmppath}/%{name}.app.files -%define filesystem_filelist %{_tmppath}/%{name}.filesystem.files +# on RHEL we got unwanted improved debugging enhancements +%define _build_id_links none + +%define package_filelist %{_builddir}/%{name}.files +%define app_filelist %{_builddir}/%{name}.app.files +%define filesystem_filelist %{_builddir}/%{name}.filesystem.files %define default_filesystem / /opt /usr /usr/bin /usr/lib /usr/local /usr/local/bin /usr/local/lib diff -Nru openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp --- openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -34,6 +34,7 @@ #include "Dll.h" #include "WinApp.h" #include "Toolbox.h" +#include "Executor.h" #include "FileUtils.h" #include "PackageFile.h" #include "UniqueHandle.h" @@ -180,29 +181,29 @@ jvm = std::unique_ptr(); - STARTUPINFOW si; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(pi)); - - if (!CreateProcessW(launcherPath.c_str(), GetCommandLineW(), - NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { - JP_THROW(SysError(tstrings::any() << "CreateProcessW() failed", - CreateProcessW)); + UniqueHandle jobHandle(CreateJobObject(NULL, NULL)); + if (jobHandle.get() == NULL) { + JP_THROW(SysError(tstrings::any() << "CreateJobObject() failed", + CreateJobObject)); + } + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { }; + jobInfo.BasicLimitInformation.LimitFlags = + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if (!SetInformationJobObject(jobHandle.get(), + JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo))) { + JP_THROW(SysError(tstrings::any() << + "SetInformationJobObject() failed", + SetInformationJobObject)); } - WaitForSingleObject(pi.hProcess, INFINITE); - - UniqueHandle childProcessHandle(pi.hProcess); - UniqueHandle childThreadHandle(pi.hThread); + Executor exec(launcherPath); + exec.visible(true).withJobObject(jobHandle.get()).suspended(true).inherit(true); + const auto args = SysInfo::getCommandArgs(); + std::for_each(args.begin(), args.end(), [&exec] (const tstring& arg) { + exec.arg(arg); + }); - DWORD exitCode; - if (!GetExitCodeProcess(pi.hProcess, &exitCode)) { - JP_THROW(SysError(tstrings::any() << "GetExitCodeProcess() failed", - GetExitCodeProcess)); - } + DWORD exitCode = static_cast(exec.execAndWaitForExit()); exit(exitCode); return; diff -Nru openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/common/Executor.cpp openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/common/Executor.cpp --- openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/common/Executor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/common/Executor.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,166 @@ +/* + * Copyright (c) 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. + */ + +#include +#include "Executor.h" +#include "Log.h" +#include "WinErrorHandling.h" + + +namespace { + +void escapeArg(std::wstring& str) { + if (str.empty()) { + return; + } + + if (str.front() == L'\"' && str.back() == L'\"' && str.size() > 1) { + return; + } + + if (str.find_first_of(L" \t") != std::wstring::npos) { + str = L'"' + str + L'"'; + } +} + +} // namespace + + +std::wstring Executor::args() const { + tstring_array tmpArgs; + // argv[0] is the module name. + tmpArgs.push_back(appPath); + tmpArgs.insert(tmpArgs.end(), argsArray.begin(), argsArray.end()); + + std::for_each(tmpArgs.begin(), tmpArgs.end(), escapeArg); + return tstrings::join(tmpArgs.begin(), tmpArgs.end(), _T(" ")); +} + + +int Executor::execAndWaitForExit() const { + UniqueHandle threadHandle; + UniqueHandle h = startProcess(&threadHandle); + + if (theSuspended) { + LOG_TRACE(tstrings::any() << "ResumeThread()"); + if (((DWORD)-1) == ResumeThread(threadHandle.get())) { + JP_THROW(SysError("ResumeThread() failed", ResumeThread)); + } + } + + const DWORD res = ::WaitForSingleObject(h.get(), INFINITE); + if (WAIT_FAILED == res) { + JP_THROW(SysError("WaitForSingleObject() failed", WaitForSingleObject)); + } + + DWORD exitCode = 0; + if (!GetExitCodeProcess(h.get(), &exitCode)) { + // Error reading process's exit code. + JP_THROW(SysError("GetExitCodeProcess() failed", GetExitCodeProcess)); + } + + const DWORD processId = GetProcessId(h.get()); + if (!processId) { + JP_THROW(SysError("GetProcessId() failed.", GetProcessId)); + } + + LOG_TRACE(tstrings::any() << "Process with PID=" << processId + << " terminated. Exit code=" << exitCode); + + return static_cast(exitCode); +} + + +UniqueHandle Executor::startProcess(UniqueHandle* threadHandle) const { + const std::wstring argsStr = args(); + + std::vector argsBuffer(argsStr.begin(), argsStr.end()); + argsBuffer.push_back(0); // terminating '\0' + + STARTUPINFO startupInfo; + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + + PROCESS_INFORMATION processInfo; + ZeroMemory(&processInfo, sizeof(processInfo)); + + DWORD creationFlags = 0; + + if (theSuspended) { + creationFlags |= CREATE_SUSPENDED; + } + + if (!theVisible) { + // For GUI applications. + startupInfo.dwFlags |= STARTF_USESHOWWINDOW; + startupInfo.wShowWindow = SW_HIDE; + + // For console applications. + creationFlags |= CREATE_NO_WINDOW; + } + + tstrings::any msg; + msg << "CreateProcess"; + if (theSuspended) { + msg << "[suspended]"; + } + if (theVisible) { + msg << "[visible]"; + } + if (theInherit) { + msg << "[inherit]"; + } + msg << "(" << appPath << ", " << argsStr << ")"; + + if (!CreateProcess(appPath.c_str(), argsBuffer.data(), NULL, NULL, + theInherit ? TRUE : FALSE, creationFlags, NULL, NULL, + &startupInfo, &processInfo)) { + msg << " failed"; + JP_THROW(SysError(msg, CreateProcess)); + } + + msg << " succeeded; PID=" << processInfo.dwProcessId; + LOG_TRACE(msg); + + if (threadHandle) { + *threadHandle = UniqueHandle(processInfo.hThread); + } else { + // Close unneeded handle immediately. + UniqueHandle(processInfo.hThread); + } + + if (jobHandle != NULL) { + LOG_TRACE(tstrings::any() << "AssignProcessToJobObject(PID=" + << processInfo.dwProcessId << ")"); + if (!AssignProcessToJobObject(jobHandle, processInfo.hProcess)) { + JP_THROW(SysError(tstrings::any() << + "AssignProcessToJobObject() failed", + AssignProcessToJobObject)); + } + } + + // Return process handle. + return UniqueHandle(processInfo.hProcess); +} diff -Nru openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/common/Executor.h openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/common/Executor.h --- openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/common/Executor.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/common/Executor.h 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 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. + */ + +#ifndef EXECUTOR_H +#define EXECUTOR_H + +#include "tstrings.h" +#include "UniqueHandle.h" + + +class Executor { +public: + explicit Executor(const std::wstring& appPath=std::wstring()) { + app(appPath).visible(false).suspended(false).withJobObject(NULL).inherit(false); + } + + /** + * Returns command line configured with arg() calls so far. + */ + std::wstring args() const; + + /** + * Set path to application to execute. + */ + Executor& app(const std::wstring& v) { + appPath = v; + return *this; + } + + /** + * Adds another command line argument. + */ + Executor& arg(const std::wstring& v) { + argsArray.push_back(v); + return *this; + } + + /** + * Controls if application window should be visible. + */ + Executor& visible(bool v) { + theVisible = v; + return *this; + } + + /** + * Controls if the process should inherit handles. + */ + Executor& inherit(bool v) { + theInherit = v; + return *this; + } + + /** + * Controls if the process should be started suspended. + */ + Executor& suspended(bool v) { + theSuspended = v; + return *this; + } + + /** + * Use the given job object with started process. + */ + Executor& withJobObject(HANDLE v) { + jobHandle = v; + return *this; + } + + /** + * Starts application process and blocks waiting when the started + * process terminates. + * Returns process exit code. + * Throws exception if process start failed. + */ + int execAndWaitForExit() const; + +private: + UniqueHandle startProcess(UniqueHandle* threadHandle=0) const; + + bool theVisible; + bool theInherit; + bool theSuspended; + HANDLE jobHandle; + tstring_array argsArray; + std::wstring appPath; +}; + +#endif // #ifndef EXECUTOR_H diff -Nru openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/msiwrapper/Executor.cpp openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/msiwrapper/Executor.cpp --- openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/msiwrapper/Executor.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/msiwrapper/Executor.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 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. - */ - -#include -#include "Executor.h" -#include "Log.h" -#include "WinErrorHandling.h" - - -namespace { - -void escapeArg(std::wstring& str) { - if (str.empty()) { - return; - } - - if (str.front() == L'\"' && str.back() == L'\"' && str.size() > 1) { - return; - } - - if (str.find_first_of(L" \t") != std::wstring::npos) { - str = L'"' + str + L'"'; - } -} - -} // namespace - - -std::wstring Executor::args() const { - tstring_array tmpArgs; - // argv[0] is the module name. - tmpArgs.push_back(appPath); - tmpArgs.insert(tmpArgs.end(), argsArray.begin(), argsArray.end()); - - std::for_each(tmpArgs.begin(), tmpArgs.end(), escapeArg); - return tstrings::join(tmpArgs.begin(), tmpArgs.end(), _T(" ")); -} - - -int Executor::execAndWaitForExit() const { - UniqueHandle h = startProcess(); - - const DWORD res = ::WaitForSingleObject(h.get(), INFINITE); - if (WAIT_FAILED == res) { - JP_THROW(SysError("WaitForSingleObject() failed", WaitForSingleObject)); - } - - DWORD exitCode = 0; - if (!GetExitCodeProcess(h.get(), &exitCode)) { - // Error reading process's exit code. - JP_THROW(SysError("GetExitCodeProcess() failed", GetExitCodeProcess)); - } - - const DWORD processId = GetProcessId(h.get()); - if (!processId) { - JP_THROW(SysError("GetProcessId() failed.", GetProcessId)); - } - - LOG_TRACE(tstrings::any() << "Process with PID=" << processId - << " terminated. Exit code=" << exitCode); - - return static_cast(exitCode); -} - - -UniqueHandle Executor::startProcess() const { - const std::wstring argsStr = args(); - - std::vector argsBuffer(argsStr.begin(), argsStr.end()); - argsBuffer.push_back(0); // terminating '\0' - - STARTUPINFO startupInfo; - ZeroMemory(&startupInfo, sizeof(startupInfo)); - startupInfo.cb = sizeof(startupInfo); - - PROCESS_INFORMATION processInfo; - ZeroMemory(&processInfo, sizeof(processInfo)); - - DWORD creationFlags = 0; - - if (!theVisible) { - // For GUI applications. - startupInfo.dwFlags |= STARTF_USESHOWWINDOW; - startupInfo.wShowWindow = SW_HIDE; - - // For console applications. - creationFlags |= CREATE_NO_WINDOW; - } - - tstrings::any msg; - msg << "CreateProcess(" << appPath << ", " << argsStr << ")"; - - if (!CreateProcess(appPath.c_str(), argsBuffer.data(), NULL, NULL, FALSE, - creationFlags, NULL, NULL, &startupInfo, &processInfo)) { - msg << " failed"; - JP_THROW(SysError(msg, CreateProcess)); - } - - msg << " succeeded; PID=" << processInfo.dwProcessId; - LOG_TRACE(msg); - - // Close unneeded handles immediately. - UniqueHandle(processInfo.hThread); - - // Return process handle. - return UniqueHandle(processInfo.hProcess); -} diff -Nru openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/msiwrapper/Executor.h openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/msiwrapper/Executor.h --- openjdk-21-21.0.1+12/src/jdk.jpackage/windows/native/msiwrapper/Executor.h 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jpackage/windows/native/msiwrapper/Executor.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 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. - */ - -#ifndef EXECUTOR_H -#define EXECUTOR_H - -#include "tstrings.h" -#include "UniqueHandle.h" - - -class Executor { -public: - explicit Executor(const std::wstring& appPath=std::wstring()) { - app(appPath).visible(false); - } - - /** - * Returns command line configured with arg() calls so far. - */ - std::wstring args() const; - - /** - * Set path to application to execute. - */ - Executor& app(const std::wstring& v) { - appPath = v; - return *this; - } - - /** - * Adds another command line argument. - */ - Executor& arg(const std::wstring& v) { - argsArray.push_back(v); - return *this; - } - - /** - * Controls if application window should be visible. - */ - Executor& visible(bool v) { - theVisible = v; - return *this; - } - - /** - * Starts application process and blocks waiting when the started - * process terminates. - * Returns process exit code. - * Throws exception if process start failed. - */ - int execAndWaitForExit() const; - -private: - UniqueHandle startProcess() const; - - bool theVisible; - tstring_array argsArray; - std::wstring appPath; -}; - -#endif // #ifndef EXECUTOR_H diff -Nru openjdk-21-21.0.1+12/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java openjdk-21-21.0.2+13/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java --- openjdk-21-21.0.1+12/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java 2024-01-16 16:19:00.000000000 +0000 @@ -306,7 +306,7 @@ AMPAMP(TokenKind.AMPAMP, XEXPR, true), // && BARBAR(TokenKind.BARBAR, XEXPR, true), // || PLUS(TokenKind.PLUS, XEXPR1, true), // + - SUB(TokenKind.SUB, XEXPR1, true), // - + SUB(TokenKind.SUB, XEXPR1 | XDECL, true), // - SLASH(TokenKind.SLASH, XEXPR, true), // / BAR(TokenKind.BAR, XEXPR, true), // | CARET(TokenKind.CARET, XEXPR, true), // ^ diff -Nru openjdk-21-21.0.1+12/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java openjdk-21-21.0.2+13/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java --- openjdk-21-21.0.1+12/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java 2024-01-16 16:19:00.000000000 +0000 @@ -68,8 +68,8 @@ } @Override - void setTcpkeepAliveProbes(int fd, final int value) throws SocketException { - setTcpkeepAliveProbes0(fd, value); + void setTcpKeepAliveProbes(int fd, final int value) throws SocketException { + setTcpKeepAliveProbes0(fd, value); } @Override @@ -83,8 +83,8 @@ } @Override - int getTcpkeepAliveProbes(int fd) throws SocketException { - return getTcpkeepAliveProbes0(fd); + int getTcpKeepAliveProbes(int fd) throws SocketException { + return getTcpKeepAliveProbes0(fd); } @Override @@ -117,11 +117,11 @@ return new UnixDomainPrincipal(user, group); } - private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException; + private static native void setTcpKeepAliveProbes0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException; private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException; - private static native int getTcpkeepAliveProbes0(int fd) throws SocketException; + private static native int getTcpKeepAliveProbes0(int fd) throws SocketException; private static native int getTcpKeepAliveTime0(int fd) throws SocketException; private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException; private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException; diff -Nru openjdk-21-21.0.1+12/src/jdk.net/aix/native/libextnet/AIXSocketOptions.c openjdk-21-21.0.2+13/src/jdk.net/aix/native/libextnet/AIXSocketOptions.c --- openjdk-21-21.0.1+12/src/jdk.net/aix/native/libextnet/AIXSocketOptions.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/aix/native/libextnet/AIXSocketOptions.c 2024-01-16 16:19:00.000000000 +0000 @@ -150,10 +150,10 @@ /* * Class: jdk_net_AIXSocketOptions - * Method: setTcpkeepAliveProbes0 + * Method: setTcpKeepAliveProbes0 * Signature: (II)V */ -JNIEXPORT void JNICALL Java_jdk_net_AIXSocketOptions_setTcpkeepAliveProbes0 +JNIEXPORT void JNICALL Java_jdk_net_AIXSocketOptions_setTcpKeepAliveProbes0 (JNIEnv *env, jobject unused, jint fd, jint optval) { jint rv = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, sizeof (optval)); handleError(env, rv, "set option TCP_KEEPCNT failed"); @@ -183,10 +183,10 @@ /* * Class: jdk_net_AIXSocketOptions - * Method: getTcpkeepAliveProbes0 + * Method: getTcpKeepAliveProbes0 * Signature: (I)I; */ -JNIEXPORT jint JNICALL Java_jdk_net_AIXSocketOptions_getTcpkeepAliveProbes0 +JNIEXPORT jint JNICALL Java_jdk_net_AIXSocketOptions_getTcpKeepAliveProbes0 (JNIEnv *env, jobject unused, jint fd) { jint optval, rv; socklen_t sz = sizeof (optval); diff -Nru openjdk-21-21.0.1+12/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java openjdk-21-21.0.2+13/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java --- openjdk-21-21.0.1+12/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java 2024-01-16 16:19:00.000000000 +0000 @@ -68,8 +68,8 @@ } @Override - void setTcpkeepAliveProbes(int fd, final int value) throws SocketException { - setTcpkeepAliveProbes0(fd, value); + void setTcpKeepAliveProbes(int fd, final int value) throws SocketException { + setTcpKeepAliveProbes0(fd, value); } @Override @@ -83,8 +83,8 @@ } @Override - int getTcpkeepAliveProbes(int fd) throws SocketException { - return getTcpkeepAliveProbes0(fd); + int getTcpKeepAliveProbes(int fd) throws SocketException { + return getTcpKeepAliveProbes0(fd); } @Override @@ -127,11 +127,11 @@ return new UnixDomainPrincipal(user, group); } - private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException; + private static native void setTcpKeepAliveProbes0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException; private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException; - private static native int getTcpkeepAliveProbes0(int fd) throws SocketException; + private static native int getTcpKeepAliveProbes0(int fd) throws SocketException; private static native int getTcpKeepAliveTime0(int fd) throws SocketException; private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException; private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException; diff -Nru openjdk-21-21.0.1+12/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c openjdk-21-21.0.2+13/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c --- openjdk-21-21.0.1+12/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c 2024-01-16 16:19:00.000000000 +0000 @@ -153,10 +153,10 @@ /* * Class: jdk_net_LinuxSocketOptions - * Method: setTcpkeepAliveProbes0 + * Method: setTcpKeepAliveProbes0 * Signature: (II)V */ -JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setTcpkeepAliveProbes0 +JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setTcpKeepAliveProbes0 (JNIEnv *env, jobject unused, jint fd, jint optval) { jint rv = setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &optval, sizeof (optval)); handleError(env, rv, "set option TCP_KEEPCNT failed"); @@ -186,10 +186,10 @@ /* * Class: jdk_net_LinuxSocketOptions - * Method: getTcpkeepAliveProbes0 + * Method: getTcpKeepAliveProbes0 * Signature: (I)I; */ -JNIEXPORT jint JNICALL Java_jdk_net_LinuxSocketOptions_getTcpkeepAliveProbes0 +JNIEXPORT jint JNICALL Java_jdk_net_LinuxSocketOptions_getTcpKeepAliveProbes0 (JNIEnv *env, jobject unused, jint fd) { jint optval, rv; socklen_t sz = sizeof (optval); diff -Nru openjdk-21-21.0.1+12/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java openjdk-21-21.0.2+13/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java --- openjdk-21-21.0.1+12/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java 2024-01-16 16:19:00.000000000 +0000 @@ -49,8 +49,8 @@ } @Override - void setTcpkeepAliveProbes(int fd, final int value) throws SocketException { - setTcpkeepAliveProbes0(fd, value); + void setTcpKeepAliveProbes(int fd, final int value) throws SocketException { + setTcpKeepAliveProbes0(fd, value); } @Override @@ -69,8 +69,8 @@ } @Override - int getTcpkeepAliveProbes(int fd) throws SocketException { - return getTcpkeepAliveProbes0(fd); + int getTcpKeepAliveProbes(int fd) throws SocketException { + return getTcpKeepAliveProbes0(fd); } @Override @@ -103,11 +103,11 @@ return new UnixDomainPrincipal(user, group); } - private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException; + private static native void setTcpKeepAliveProbes0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException; private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException; - private static native int getTcpkeepAliveProbes0(int fd) throws SocketException; + private static native int getTcpKeepAliveProbes0(int fd) throws SocketException; private static native int getTcpKeepAliveTime0(int fd) throws SocketException; private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException; private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException; diff -Nru openjdk-21-21.0.1+12/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c openjdk-21-21.0.2+13/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c --- openjdk-21-21.0.1+12/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c 2024-01-16 16:19:00.000000000 +0000 @@ -96,10 +96,10 @@ /* * Class: jdk_net_MacOSXSocketOptions - * Method: setTcpkeepAliveProbes0 + * Method: setTcpKeepAliveProbes0 * Signature: (II)V */ -JNIEXPORT void JNICALL Java_jdk_net_MacOSXSocketOptions_setTcpkeepAliveProbes0 +JNIEXPORT void JNICALL Java_jdk_net_MacOSXSocketOptions_setTcpKeepAliveProbes0 (JNIEnv *env, jobject unused, jint fd, jint optval) { jint rv = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, sizeof (optval)); handleError(env, rv, "set option TCP_KEEPCNT failed"); @@ -129,10 +129,10 @@ /* * Class: jdk_net_MacOSXSocketOptions - * Method: getTcpkeepAliveProbes0 + * Method: getTcpKeepAliveProbes0 * Signature: (I)I; */ -JNIEXPORT jint JNICALL Java_jdk_net_MacOSXSocketOptions_getTcpkeepAliveProbes0 +JNIEXPORT jint JNICALL Java_jdk_net_MacOSXSocketOptions_getTcpKeepAliveProbes0 (JNIEnv *env, jobject unused, jint fd) { jint optval, rv; socklen_t sz = sizeof (optval); diff -Nru openjdk-21-21.0.1+12/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java openjdk-21-21.0.2+13/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java --- openjdk-21-21.0.1+12/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java 2024-01-16 16:19:00.000000000 +0000 @@ -277,7 +277,7 @@ if (option == TCP_QUICKACK) { setQuickAckOption(fd, (boolean) value); } else if (option == TCP_KEEPCOUNT) { - setTcpkeepAliveProbes(fd, (Integer) value); + setTcpKeepAliveProbes(fd, (Integer) value); } else if (option == IP_DONTFRAGMENT) { setIpDontFragment(fd, (Boolean) value, isIPv6); } else if (option == TCP_KEEPIDLE) { @@ -307,7 +307,7 @@ if (option == TCP_QUICKACK) { return getQuickAckOption(fd); } else if (option == TCP_KEEPCOUNT) { - return getTcpkeepAliveProbes(fd); + return getTcpKeepAliveProbes(fd); } else if (option == IP_DONTFRAGMENT) { return getIpDontFragment(fd, isIPv6); } else if (option == TCP_KEEPIDLE) { @@ -343,9 +343,9 @@ return platformSocketOptions.getQuickAck(fdAccess.get(fd)); } - private static void setTcpkeepAliveProbes(FileDescriptor fd, int value) + private static void setTcpKeepAliveProbes(FileDescriptor fd, int value) throws SocketException { - platformSocketOptions.setTcpkeepAliveProbes(fdAccess.get(fd), value); + platformSocketOptions.setTcpKeepAliveProbes(fdAccess.get(fd), value); } private static void setTcpKeepAliveTime(FileDescriptor fd, int value) @@ -363,8 +363,8 @@ platformSocketOptions.setTcpKeepAliveIntvl(fdAccess.get(fd), value); } - private static int getTcpkeepAliveProbes(FileDescriptor fd) throws SocketException { - return platformSocketOptions.getTcpkeepAliveProbes(fdAccess.get(fd)); + private static int getTcpKeepAliveProbes(FileDescriptor fd) throws SocketException { + return platformSocketOptions.getTcpKeepAliveProbes(fdAccess.get(fd)); } private static boolean getIpDontFragment(FileDescriptor fd, boolean isIPv6) throws SocketException { @@ -438,7 +438,7 @@ return false; } - void setTcpkeepAliveProbes(int fd, final int value) throws SocketException { + void setTcpKeepAliveProbes(int fd, final int value) throws SocketException { throw new UnsupportedOperationException("unsupported TCP_KEEPCNT option"); } @@ -462,7 +462,7 @@ throw new UnsupportedOperationException("unsupported IP_DONTFRAGMENT option"); } - int getTcpkeepAliveProbes(int fd) throws SocketException { + int getTcpKeepAliveProbes(int fd) throws SocketException { throw new UnsupportedOperationException("unsupported TCP_KEEPCNT option"); } diff -Nru openjdk-21-21.0.1+12/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java openjdk-21-21.0.2+13/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java --- openjdk-21-21.0.1+12/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -42,6 +42,11 @@ } @Override + boolean keepAliveOptionsSupported() { + return keepAliveOptionsSupported0(); + } + + @Override void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException { setIpDontFragment0(fd, value, isIPv6); } @@ -51,8 +56,45 @@ return getIpDontFragment0(fd, isIPv6); } + @Override + void setTcpKeepAliveProbes(int fd, final int value) throws SocketException { + setTcpKeepAliveProbes0(fd, value); + } + + @Override + int getTcpKeepAliveProbes(int fd) throws SocketException { + return getTcpKeepAliveProbes0(fd); + } + + @Override + void setTcpKeepAliveTime(int fd, final int value) throws SocketException { + setTcpKeepAliveTime0(fd, value); + } + + @Override + int getTcpKeepAliveTime(int fd) throws SocketException { + return getTcpKeepAliveTime0(fd); + } + + @Override + void setTcpKeepAliveIntvl(int fd, final int value) throws SocketException { + setTcpKeepAliveIntvl0(fd, value); + } + + @Override + int getTcpKeepAliveIntvl(int fd) throws SocketException { + return getTcpKeepAliveIntvl0(fd); + } + + private static native boolean keepAliveOptionsSupported0(); private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException; private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException; + private static native void setTcpKeepAliveProbes0(int fd, int value) throws SocketException; + private static native int getTcpKeepAliveProbes0(int fd) throws SocketException; + private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException; + private static native int getTcpKeepAliveTime0(int fd) throws SocketException; + private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException; + private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException; static { if (System.getSecurityManager() == null) { diff -Nru openjdk-21-21.0.1+12/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c openjdk-21-21.0.2+13/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c --- openjdk-21-21.0.1+12/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -34,7 +34,8 @@ static void handleError(JNIEnv *env, jint rv, const char *errmsg) { if (rv < 0) { - if (errno == ENOPROTOOPT) { + int error = WSAGetLastError(); + if (error == WSAENOPROTOOPT) { JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "unsupported socket option"); } else { @@ -43,6 +44,57 @@ } } +static jint socketOptionSupported(jint level, jint optname) { + WSADATA wsaData; + jint error = WSAStartup(MAKEWORD(2, 2), &wsaData); + + if (error != 0) { + return 0; + } + + SOCKET sock; + jint one = 1; + jint rv; + socklen_t sz = sizeof(one); + + /* First try IPv6; fall back to IPv4. */ + sock = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); + if (sock == INVALID_SOCKET) { + error = WSAGetLastError(); + if (error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT) { + sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + } + if (sock == INVALID_SOCKET) { + return 0; + } + } + + rv = getsockopt(sock, level, optname, (char*) &one, &sz); + error = WSAGetLastError(); + + if (rv != 0 && error == WSAENOPROTOOPT) { + rv = 0; + } else { + rv = 1; + } + + closesocket(sock); + WSACleanup(); + + return rv; +} + +/* + * Class: jdk_net_WindowsSocketOptions + * Method: keepAliveOptionsSupported0 + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_jdk_net_WindowsSocketOptions_keepAliveOptionsSupported0 +(JNIEnv *env, jobject unused) { + return socketOptionSupported(IPPROTO_TCP, TCP_KEEPIDLE) && socketOptionSupported(IPPROTO_TCP, TCP_KEEPCNT) + && socketOptionSupported(IPPROTO_TCP, TCP_KEEPINTVL); +} + /* * Class: jdk_net_WindowsSocketOptions * Method: setIpDontFragment0 @@ -103,3 +155,78 @@ } } +/* + * Class: jdk_net_WindowsSocketOptions + * Method: setTcpKeepAliveProbes0 + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setTcpKeepAliveProbes0 +(JNIEnv *env, jobject unused, jint fd, jint optval) { + jint rv = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, (char*) &optval, sizeof(optval)); + handleError(env, rv, "set option TCP_KEEPCNT failed"); +} + +/* + * Class: jdk_net_WindowsSocketOptions + * Method: getTcpKeepAliveProbes0 + * Signature: (I)I; + */ +JNIEXPORT jint JNICALL Java_jdk_net_WindowsSocketOptions_getTcpKeepAliveProbes0 +(JNIEnv *env, jobject unused, jint fd) { + jint optval, rv; + socklen_t sz = sizeof(optval); + rv = getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, (char*) &optval, &sz); + handleError(env, rv, "get option TCP_KEEPCNT failed"); + return optval; +} + +/* + * Class: jdk_net_WindowsSocketOptions + * Method: setTcpKeepAliveTime0 + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setTcpKeepAliveTime0 +(JNIEnv *env, jobject unused, jint fd, jint optval) { + jint rv = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (char*) &optval, sizeof(optval)); + handleError(env, rv, "set option TCP_KEEPIDLE failed"); +} + +/* + * Class: jdk_net_WindowsSocketOptions + * Method: getTcpKeepAliveTime0 + * Signature: (I)I; + */ +JNIEXPORT jint JNICALL Java_jdk_net_WindowsSocketOptions_getTcpKeepAliveTime0 +(JNIEnv *env, jobject unused, jint fd) { + jint optval, rv; + socklen_t sz = sizeof(optval); + rv = getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (char*) &optval, &sz); + handleError(env, rv, "get option TCP_KEEPIDLE failed"); + return optval; +} + +/* + * Class: jdk_net_WindowsSocketOptions + * Method: setTcpKeepAliveIntvl0 + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setTcpKeepAliveIntvl0 +(JNIEnv *env, jobject unused, jint fd, jint optval) { + jint rv = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (char*) &optval, sizeof(optval)); + handleError(env, rv, "set option TCP_KEEPINTVL failed"); +} + +/* + * Class: jdk_net_WindowsSocketOptions + * Method: getTcpKeepAliveIntvl0 + * Signature: (I)I; + */ +JNIEXPORT jint JNICALL Java_jdk_net_WindowsSocketOptions_getTcpKeepAliveIntvl0 +(JNIEnv *env, jobject unused, jint fd) { + jint optval, rv; + socklen_t sz = sizeof(optval); + rv = getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (char*) &optval, &sz); + handleError(env, rv, "get option TCP_KEEPINTVL failed"); + return optval; +} + diff -Nru openjdk-21-21.0.1+12/test/hotspot/gtest/logging/test_logTagSet.cpp openjdk-21-21.0.2+13/test/hotspot/gtest/logging/test_logTagSet.cpp --- openjdk-21-21.0.1+12/test/hotspot/gtest/logging/test_logTagSet.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/gtest/logging/test_logTagSet.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -31,7 +31,7 @@ #include "unittest.hpp" // Test the default level for each tagset -TEST(LogTagSet, defaults) { +TEST_VM(LogTagSet, defaults) { for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { char buf[256]; ts->label(buf, sizeof(buf)); @@ -44,7 +44,7 @@ } } -TEST(LogTagSet, has_output) { +TEST_VM(LogTagSet, has_output) { LogTagSet& ts = LogTagSetMapping::tagset(); ts.set_output_level(StderrLog, LogLevel::Trace); EXPECT_TRUE(ts.has_output(StderrLog)); @@ -53,14 +53,14 @@ EXPECT_FALSE(ts.has_output(StderrLog)); } -TEST(LogTagSet, ntags) { +TEST_VM(LogTagSet, ntags) { const LogTagSet& ts = LogTagSetMapping::tagset(); EXPECT_EQ(1u, ts.ntags()); const LogTagSet& ts2 = LogTagSetMapping::tagset(); EXPECT_EQ(5u, ts2.ntags()); } -TEST(LogTagSet, is_level) { +TEST_VM(LogTagSet, is_level) { LogTagSet& ts = LogTagSetMapping::tagset(); // Set info level on stdout and verify that is_level() reports correctly ts.set_output_level(StdoutLog, LogLevel::Info); @@ -71,9 +71,10 @@ EXPECT_FALSE(ts.is_level(LogLevel::Trace)); ts.set_output_level(StdoutLog, LogLevel::Default); EXPECT_TRUE(ts.is_level(LogLevel::Default)); + ts.set_output_level(StdoutLog, LogLevel::Off); } -TEST(LogTagSet, level_for) { +TEST_VM(LogTagSet, level_for) { LogOutput* output = StdoutLog; LogTagSet& ts = LogTagSetMapping::tagset(); for (uint i = 0; i < LogLevel::Count; i++) { @@ -82,10 +83,10 @@ ts.set_output_level(output, level); EXPECT_EQ(level, ts.level_for(output)); } - ts.set_output_level(output, LogLevel::Default); + ts.set_output_level(output, LogLevel::Off); } -TEST(LogTagSet, contains) { +TEST_VM(LogTagSet, contains) { // Verify that contains works as intended for a few predetermined tagsets const LogTagSet& ts = LogTagSetMapping::tagset(); EXPECT_TRUE(ts.contains(PREFIX_LOG_TAG(logging))); @@ -111,7 +112,7 @@ EXPECT_TRUE(ts4.contains(PREFIX_LOG_TAG(heap))); } -TEST(LogTagSet, label) { +TEST_VM(LogTagSet, label) { char buf[256]; const LogTagSet& ts = LogTagSetMapping::tagset(); ASSERT_NE(-1, ts.label(buf, sizeof(buf))); @@ -137,7 +138,7 @@ } -TEST(LogTagSet, duplicates) { +TEST_VM(LogTagSet, duplicates) { for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { char ts_name[512]; ts->label(ts_name, sizeof(ts_name), ","); diff -Nru openjdk-21-21.0.1+12/test/hotspot/gtest/runtime/test_atomic.cpp openjdk-21-21.0.2+13/test/hotspot/gtest/runtime/test_atomic.cpp --- openjdk-21-21.0.1+12/test/hotspot/gtest/runtime/test_atomic.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/gtest/runtime/test_atomic.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -53,7 +53,7 @@ } }; -TEST(AtomicAddTest, int32) { +TEST_VM(AtomicAddTest, int32) { using Support = AtomicAddTestSupport; Support().test_add(); Support().test_fetch_add(); @@ -61,14 +61,14 @@ // 64bit Atomic::add is only supported on 64bit platforms. #ifdef _LP64 -TEST(AtomicAddTest, int64) { +TEST_VM(AtomicAddTest, int64) { using Support = AtomicAddTestSupport; Support().test_add(); Support().test_fetch_add(); } #endif // _LP64 -TEST(AtomicAddTest, ptr) { +TEST_VM(AtomicAddTest, ptr) { uint _test_values[10] = {}; uint* volatile _test_value{}; @@ -103,14 +103,14 @@ } }; -TEST(AtomicXchgTest, int32) { +TEST_VM(AtomicXchgTest, int32) { using Support = AtomicXchgTestSupport; Support().test(); } // 64bit Atomic::xchg is only supported on 64bit platforms. #ifdef _LP64 -TEST(AtomicXchgTest, int64) { +TEST_VM(AtomicXchgTest, int64) { using Support = AtomicXchgTestSupport; Support().test(); } @@ -136,16 +136,61 @@ } }; -TEST(AtomicCmpxchgTest, int32) { +TEST_VM(AtomicCmpxchgTest, int32) { using Support = AtomicCmpxchgTestSupport; Support().test(); } -TEST(AtomicCmpxchgTest, int64) { +TEST_VM(AtomicCmpxchgTest, int64) { using Support = AtomicCmpxchgTestSupport; Support().test(); } +struct AtomicCmpxchg1ByteStressSupport { + char _default_val; + int _base; + char _array[7+32+7]; + + AtomicCmpxchg1ByteStressSupport() : _default_val(0x7a), _base(7), _array{} {} + + void validate(char val, char val2, int index) { + for (int i = 0; i < 7; i++) { + EXPECT_EQ(_array[i], _default_val); + } + for (int i = 7; i < (7+32); i++) { + if (i == index) { + EXPECT_EQ(_array[i], val2); + } else { + EXPECT_EQ(_array[i], val); + } + } + for (int i = 0; i < 7; i++) { + EXPECT_EQ(_array[i], _default_val); + } + } + + void test_index(int index) { + char one = 1; + Atomic::cmpxchg(&_array[index], _default_val, one); + validate(_default_val, one, index); + + Atomic::cmpxchg(&_array[index], one, _default_val); + validate(_default_val, _default_val, index); + } + + void test() { + memset(_array, _default_val, sizeof(_array)); + for (int i = _base; i < (_base+32); i++) { + test_index(i); + } + } +}; + +TEST_VM(AtomicCmpxchg1Byte, stress) { + AtomicCmpxchg1ByteStressSupport support; + support.test(); +} + template struct AtomicEnumTestSupport { volatile T _test_value; @@ -179,7 +224,7 @@ enum TestEnum { A, B, C }; } -TEST(AtomicEnumTest, unscoped_enum) { +TEST_VM(AtomicEnumTest, unscoped_enum) { using namespace AtomicEnumTestUnscoped; using Support = AtomicEnumTestSupport; @@ -190,7 +235,7 @@ enum class AtomicEnumTestScoped { A, B, C }; -TEST(AtomicEnumTest, scoped_enum) { +TEST_VM(AtomicEnumTest, scoped_enum) { const AtomicEnumTestScoped B = AtomicEnumTestScoped::B; const AtomicEnumTestScoped C = AtomicEnumTestScoped::C; using Support = AtomicEnumTestSupport; @@ -284,28 +329,28 @@ template const T AtomicBitopsTestSupport::_change_value; -TEST(AtomicBitopsTest, int8) { +TEST_VM(AtomicBitopsTest, int8) { AtomicBitopsTestSupport()(); } -TEST(AtomicBitopsTest, uint8) { +TEST_VM(AtomicBitopsTest, uint8) { AtomicBitopsTestSupport()(); } -TEST(AtomicBitopsTest, int32) { +TEST_VM(AtomicBitopsTest, int32) { AtomicBitopsTestSupport()(); } -TEST(AtomicBitopsTest, uint32) { +TEST_VM(AtomicBitopsTest, uint32) { AtomicBitopsTestSupport()(); } #ifdef _LP64 -TEST(AtomicBitopsTest, int64) { +TEST_VM(AtomicBitopsTest, int64) { AtomicBitopsTestSupport()(); } -TEST(AtomicBitopsTest, uint64) { +TEST_VM(AtomicBitopsTest, uint64) { AtomicBitopsTestSupport()(); } #endif // _LP64 diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/ProblemList-zgc.txt openjdk-21-21.0.2+13/test/hotspot/jtreg/ProblemList-zgc.txt --- openjdk-21-21.0.1+12/test/hotspot/jtreg/ProblemList-zgc.txt 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/ProblemList-zgc.txt 2024-01-16 16:19:00.000000000 +0000 @@ -45,4 +45,3 @@ vmTestbase/nsk/monitoring/MemoryPoolMBean/isCollectionUsageThresholdExceeded/isexceeded002/TestDescription.java 8298302 generic-all vmTestbase/nsk/sysdict/vm/stress/chain/chain007/chain007.java 8298991 linux-x64 -serviceability/jvmti/vthread/FollowReferences/VThreadStackRefTest.java#default 8309663 linux-x64 diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/ProblemList.txt openjdk-21-21.0.2+13/test/hotspot/jtreg/ProblemList.txt --- openjdk-21-21.0.1+12/test/hotspot/jtreg/ProblemList.txt 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/ProblemList.txt 2024-01-16 16:19:00.000000000 +0000 @@ -64,6 +64,7 @@ compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263,8307907 generic-x64,generic-i586,aix-ppc64 compiler/c2/Test8004741.java 8235801 generic-all +compiler/c2/irTests/TestDuplicateBackedge.java 8318904 generic-all compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-all @@ -91,8 +92,7 @@ # :hotspot_runtime - -runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64 +runtime/jni/terminatedThread/TestTerminatedThread.java 8317789 aix-ppc64 runtime/handshake/HandshakeSuspendExitTest.java 8294313 generic-all runtime/os/TestTracePageSizes.java#no-options 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#explicit-large-page-size 8267460 linux-aarch64 @@ -109,7 +109,7 @@ applications/jcstress/copy.java 8229852 linux-all containers/docker/TestJcmd.java 8278102 linux-all -containers/docker/TestMemoryAwareness.java 8303470 linux-x64 +containers/docker/TestMemoryAwareness.java 8303470 linux-all ############################################################################# @@ -120,7 +120,7 @@ serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java 8225354 windows-all serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java 8286836 generic-all -serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64 +serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64,aix-ppc64 serviceability/sa/ClhsdbCDSCore.java 8294316,8267433 macosx-x64 serviceability/sa/ClhsdbFindPC.java#xcomp-core 8294316,8267433 macosx-x64 @@ -138,8 +138,6 @@ ############################################################################# -gtest/NMTGtests.java#nmt-detail 8306561 aix-ppc64 -gtest/NMTGtests.java#nmt-summary 8306561 aix-ppc64 ############################################################################# @@ -154,9 +152,6 @@ vmTestbase/nsk/jvmti/AttachOnDemand/attach002a/TestDescription.java 8307462 generic-all vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java 8202971 generic-all -vmTestbase/nsk/jvmti/scenarios/jni_interception/JI05/ji05t001/TestDescription.java 8219652 aix-ppc64 -vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64 -vmTestbase/nsk/jvmti/SetJNIFunctionTable/setjniftab001/TestDescription.java 8219652 aix-ppc64 vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8073470 linux-all vmTestbase/nsk/jvmti/InterruptThread/intrpthrd003/TestDescription.java 8288911 macosx-x64 diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/TEST.ROOT openjdk-21-21.0.2+13/test/hotspot/jtreg/TEST.ROOT --- openjdk-21-21.0.1+12/test/hotspot/jtreg/TEST.ROOT 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/TEST.ROOT 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -85,7 +85,7 @@ jdk.containerized # Minimum jtreg version -requiredVersion=7.2+1 +requiredVersion=7.3.1+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../../ notation to reach them diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/applications/scimark/Scimark.java openjdk-21-21.0.2+13/test/hotspot/jtreg/applications/scimark/Scimark.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/applications/scimark/Scimark.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/applications/scimark/Scimark.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -24,7 +24,6 @@ /* * @test * @library /test/lib - * @requires vm.flagless * @run driver Scimark */ @@ -47,7 +46,9 @@ + Scimark.class.getName(), e); } - OutputAnalyzer output = new OutputAnalyzer(ProcessTools.createJavaProcessBuilder( + System.setProperty("test.noclasspath", "true"); + + OutputAnalyzer output = new OutputAnalyzer(ProcessTools.createTestJvm( "-cp", artifacts.get("gov.nist.math.scimark-2.0").toString(), "jnt.scimark2.commandline", "-large") .start()); diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/allocation/TestNewMaxLengthArray.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/allocation/TestNewMaxLengthArray.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/allocation/TestNewMaxLengthArray.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/allocation/TestNewMaxLengthArray.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * 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 8316414 + * @summary C2: large byte array clone triggers "failed: malformed control flow" assertion failure on linux-x86 + * @run main/othervm -Xcomp -XX:CompileOnly=TestNewMaxLengthArray::createAndClone TestNewMaxLengthArray + */ + +public class TestNewMaxLengthArray { + + // Maximum length of a byte array on a 32-bits platform using default object + // alignment (8 bytes). + static final int MAX_BYTE_ARRAY_LENGTH = 0x7ffffffc; + + public static byte[] createAndClone() { + byte[] array = new byte[MAX_BYTE_ARRAY_LENGTH]; + return array.clone(); + } + + public static void main(String[] a) { + try { + createAndClone(); + } catch (OutOfMemoryError oome) { + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/arraycopy/TestCloneArrayWithDifferentLengthConstness.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/arraycopy/TestCloneArrayWithDifferentLengthConstness.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/arraycopy/TestCloneArrayWithDifferentLengthConstness.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/arraycopy/TestCloneArrayWithDifferentLengthConstness.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * 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 compiler.arraycopy; + +/** + * @test + * @bug 8315082 + * @summary Test that idealization of clone-derived ArrayCopy nodes does not + * trigger assertion failures for different combinations of + * constant/variable array length (in number of elements) and array + * copy length (in words). + * @run main/othervm -Xbatch -XX:-TieredCompilation + * -XX:CompileOnly=compiler.arraycopy.TestCloneArrayWithDifferentLengthConstness::test* + * compiler.arraycopy.TestCloneArrayWithDifferentLengthConstness + */ + +public class TestCloneArrayWithDifferentLengthConstness { + + public static void main(String[] args) { + for (int i = 0; i < 10_000; i++) { + testConstantArrayLengthAndConstantArrayCopyLength(); + } + for (int i = 0; i < 10_000; i++) { + testVariableArrayLengthAndConstantArrayCopyLength(i % 2 == 0); + } + for (int i = 0; i < 10_000; i++) { + testVariableArrayLengthAndVariableArrayCopyLength(i % 2 == 0); + } + } + + static int[] testConstantArrayLengthAndConstantArrayCopyLength() { + int[] src = new int[3]; + return (int[])src.clone(); + } + + static int[] testVariableArrayLengthAndConstantArrayCopyLength(boolean p) { + int[] src = new int[p ? 3 : 4]; + return (int[])src.clone(); + } + + static int[] testVariableArrayLengthAndVariableArrayCopyLength(boolean p) { + int[] src = new int[p ? 3 : 42]; + return (int[])src.clone(); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/c1/Test8301489.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/c1/Test8301489.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/c1/Test8301489.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/c1/Test8301489.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * 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 8301489 + * @summary ShortLoopOptimizer might lift instructions before their inputs + * @requires vm.compiler1.enabled + * @run main/othervm -Xcomp -XX:TieredStopAtLevel=1 + * -XX:CompileOnly=compiler.c1.Test8301489::* + * compiler.c1.Test8301489 + */ + + +package compiler.c1; + +public class Test8301489 { + static int c = 0; + static int[] arr = {}; + + static void op2Test(int a, int b) { + // Implicit edges created during dom calculation to exception handler + if (a < 0) { + b = 0; + } + // Create two branches into next loop header block + try { + int l = arr.length; + for (int i = 0; i < l; i++) { + int d = arr[i] + arr[i]; + } + } + // Exception handler as predecessor of the next loop header block + catch (ArithmeticException e) {} + + // op2(a, b) as candidate for hoisting: operands are loop invariant + while (a + b < b) {} + // op2(a, b) should not be hoisted above 'if (a < 0) {...}' block + } + + static void arrayLengthTest() { + float [] newArr = new float[c]; + + try { + for (float f : newArr) {} + } + catch (ArrayIndexOutOfBoundsException e) {} + + while (54321 < newArr.length) { + newArr[c] = 123.45f; + } + } + + static void negateTest(int a) { + if (a <= 111) { + a = -111; + } + + int f = 0; + try { + int l = arr.length; + f--; + } + catch (NegativeArraySizeException e) {} + + while (-a < f) { + f--; + } + } + + static void convertTest(int a) { + if (c == 0) { + a = 0; + } + + long tgt = 10; + + try { + String s = String.valueOf(c); + } + catch (NumberFormatException e) {} + + while ((long)a != tgt) { + tgt--; + } + } + + public static void main(String[] args) { + for (int i = 0; i < 3; i++) { + op2Test(12, 34); + arrayLengthTest(); + negateTest(-778); + convertTest(4812); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * 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 compiler.c2; + +/* + * @test + * @bug 8314191 + * @summary Loop increment should not be transformed into unsigned comparison + * + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,*MinValueStrideCountedLoop::test* + * compiler.c2.MinValueStrideCountedLoop + */ + +/* + * @test + * @bug 8316719 + * @summary Loop increment should not be transformed into unsigned comparison + * @requires vm.compiler2.enabled + * @run main/othervm -Xcomp -XX:-TieredCompilation -XX:-UseLoopPredicate + * -XX:CompileCommand=compileonly,*MinValueStrideCountedLoop::test* + * compiler.c2.MinValueStrideCountedLoop + */ +public class MinValueStrideCountedLoop { + static int limit = 0; + static int res = 0; + static int[] array = new int[1]; + static boolean b; + + static void test1() { + for (int i = 0; i >= limit + -2147483647; i += -2147483648) { + res += 42; + } + } + + static int test2(int init, int limit) { + int res = 0; + int i = init; + do { + if (b) { } + res += array[i]; + i += -2147483648; + } while (i >= limit + -2147483647); + return res; + } + + public static void main(String[] args) { + test1(); + test2(0, 0); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/c2/TestLargeTreeOfSubNodes.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/c2/TestLargeTreeOfSubNodes.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/c2/TestLargeTreeOfSubNodes.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/c2/TestLargeTreeOfSubNodes.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8316396 + * @summary Endless loop in C2 compilation triggered by AddNode::IdealIL + * @run main/othervm -XX:CompileCommand=compileonly,*TestLargeTreeOfSubNodes*::test -XX:-TieredCompilation -Xcomp TestLargeTreeOfSubNodes + */ + +public class TestLargeTreeOfSubNodes { + public static long res = 0; + + public static void test() { + int a = -1, b = 0; + for (int i = 0; i < 100; ++i) { + for (int j = 0; j < 10; ++j) { + for (int k = 0; k < 1; ++k) { + } + b -= a; + a += b; + } + } + res = a; + } + + public static void main(String[] args) { + test(); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/compilercontrol/TestConflictInlineCommands.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/compilercontrol/TestConflictInlineCommands.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/compilercontrol/TestConflictInlineCommands.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/compilercontrol/TestConflictInlineCommands.java 2024-01-16 16:19:00.000000000 +0000 @@ -40,6 +40,7 @@ public class TestConflictInlineCommands { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xbatch", "-XX:CompileCommand=inline,*TestConflictInlineCommands::caller", "-XX:CompileCommand=dontinline,*TestConflictInlineCommands::caller", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,*Launcher::main", @@ -52,6 +53,7 @@ analyzer.shouldNotContain("force inline by CompileCommand"); pb = ProcessTools.createJavaProcessBuilder( + "-Xbatch", "-XX:CompileCommand=dontinline,*TestConflictInlineCommands::*caller", "-XX:CompileCommand=inline,*TestConflictInlineCommands::caller", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,*Launcher::main", @@ -77,6 +79,9 @@ sum += caller(i, 0); } } + System.out.println("sum is:" + sum); + System.out.flush(); + System.err.flush(); } } } diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8303737 + * @summary C2: cast nodes from PhiNode::Ideal() cause "Base pointers must match" assert failure + * @requires vm.gc.Parallel + * @requires vm.compiler2.enabled + * @run main/othervm -XX:-BackgroundCompilation -XX:LoopMaxUnroll=2 -XX:+UseParallelGC -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN + * -XX:-UseLoopPredicate -XX:-UseProfiledLoopPredicate -XX:StressSeed=2953783466 TestAddPChainMismatchedBase + * @run main/othervm -XX:-BackgroundCompilation -XX:LoopMaxUnroll=2 -XX:+UseParallelGC -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN + * -XX:-UseLoopPredicate -XX:-UseProfiledLoopPredicate TestAddPChainMismatchedBase + */ + +public class TestAddPChainMismatchedBase { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(); + testHelper(null, true); + testHelper2(1000); + } + } + + private static void test() { + int l; + for (l = 0; l < 5; l++) { + for (int i = 0; i < 2; i++) { + } + } + testHelper2(l); + } + + private static void testHelper2(int l) { + int[] array = new int[1000]; + if (l == 5) { + l = 4; + } else { + l = 1000; + } + for (int k = 0; k < 2; k++) { + int v = 0; + int i = 0; + for (; ; ) { + synchronized (new Object()) { + } + array = testHelper(array, false); + v += array[i]; + int j = i; + i++; + if (i >= l) { + break; + } + array[j] = v; + } + } + } + + private static int[] testHelper(int[] array, boolean flag) { + if (flag) { + return new int[1000]; + } + return array; + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase2.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase2.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase2.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/controldependency/TestAddPChainMismatchedBase2.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8303737 + * @summary C2: cast nodes from PhiNode::Ideal() cause "Base pointers must match" assert failure + * @run main/othervm -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN -XX:+StressCCP -Xcomp + * -XX:CompileOnly=TestAddPChainMismatchedBase2::* -XX:StressSeed=1581936900 TestAddPChainMismatchedBase2 + * @run main/othervm -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN -XX:+StressCCP -Xcomp + * -XX:CompileOnly=TestAddPChainMismatchedBase2::* TestAddPChainMismatchedBase2 + */ + +public class TestAddPChainMismatchedBase2 { + static final int N = 400; + static int iFld; + + public static void main(String[] strArr) { + test(8); + } + + static void test(int i2) { + int i12 = 4, iArr1[] = new int[N]; + double d1, dArr2[] = new double[N]; + do { + iArr1[i12] = 400907; + try { + iArr1[1] = 47 % i2; + } catch (ArithmeticException a_e) { + } + iArr1[i12 + 1] -= d1 = 1; + while ((d1 += 2) < 5) { + iArr1 = iArr1; + iArr1[6] = 3; + } + } while (++i12 < 14); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/controldependency/TestLoadBypassesClassCast.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/controldependency/TestLoadBypassesClassCast.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/controldependency/TestLoadBypassesClassCast.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/controldependency/TestLoadBypassesClassCast.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8303737 + * @summary C2: Load can bypass subtype check that enforces it's from the right object type + * @requires vm.gc.Parallel + * @requires vm.compiler2.enabled + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileOnly=TestLoadBypassesClassCast::test + * -XX:CompileThreshold=20000 -XX:LoopMaxUnroll=1 -XX:-LoopUnswitching -XX:+UseParallelGC TestLoadBypassesClassCast + * + */ + +public class TestLoadBypassesClassCast { + private static Object saved_o; + private static Object field_o = new A(); + private static Object saved_casted_o; + private static float barrier; + private static Object[] memory = new Object[100]; + + public static void main(String[] args) { + float[] array = new float[100]; + A a = new A(); + B b = new B(); + C c = new C(); + D d = new D(); + + // create garbage so GC runs + Thread thread = new Thread() { + public void run() { + while (true) { + int[] array = new int[1000]; + } + } + }; + + thread.setDaemon(true); + thread.start(); + + for (int i = 0; i < 20_000; i++) { + test(true, a, array, true, false); + test(false, b, array, true, false); + test(false, d, array, true, true); + test(true, a, array, false, false); + test(false, b, array, false, false); + testHelper2(42); + testHelper3(true, 42); + } + for (int j = 0; j < 1000; j++) { + for (int i = 0; i < 1_000_000; i++) { + test(false, d, array, true, true); + } + } + } + + private static int test(boolean flag, Object o, float[] array, boolean flag2, boolean flag3) { + int ret = (int)array[2]; + if (o == null) { + } + saved_o = o; // (CastPP o): cast to not null + + // A.objectField load from o hosted here even though o was not checked to be of type A + // result of the load doesn't hold an oop if o is not an A + if (flag2) { + for (int i = 1; i < 100; i *= 2) { + // safepoint here with result of load above live and expected to be an oop. Not the case + // if o is of type D: crash in gc code + } + + if (flag3) { + } else { + saved_casted_o = (A) o; // (CheckCastPP (CastPP o)): cast to not null A + + int j; + for (j = 1; j < 2; j *= 2) { + + } + + testHelper3(flag, j); // goes away after CCP + + int i; + for (i = 0; i < 2; i++) { + } + // array[2] after one round of loop opts, control + // dependent on range check, range check replaced by + // array[2] range check above, control dependent + // nodes become control dependent on that range check + ret += array[i]; + + Object o2; + if (flag) { + o2 = saved_casted_o; // (CheckCastPP (CastPP o)): cast to to not null A + } else { + o2 = testHelper2(i); // (CastPP o) after 1 round of loop opts: cast to not null + } + // subtype check split thru Phi. CheckCastPP becomes control dependent on merge point + // phi becomes (CastPP o) after 1 round of loop opts: cast to not null + // subtype check from split thru phi in one branch of the if replaced by dominating one + // empty if blocks, if goes away. CheckCastPP becomes control dependent on range check above + // CastPP replaced by dominating CastPP for null check + A a = (A) o2; + ret += a.objectField.intField; + } + } else { + // same logic as above so if this a.objectField load and + // the one above lose their dependency on the type check + // they common above all ifs + saved_casted_o = (A) o; + + int j; + for (j = 1; j < 2; j *= 2) { + + } + + testHelper3(flag, j); + + int i; + for (i = 0; i < 2; i++) { + } + ret += array[i]; + + Object o2; + if (flag) { + o2 = saved_casted_o; + } else { + o2 = testHelper2(i); + } + A a = (A) o2; + ret += a.objectField.intField; + ret += barrier; + } + + return ret; + } + + private static void testHelper3(boolean flag, int j) { + if (j == 2) { + if (flag) { + barrier = 42; + } + } + } + + private static Object testHelper2(int i) { + Object o2; + if (i == 2) { + o2 = saved_o; + } else { + o2 = field_o; + if (o2 == null) { + } + } + return o2; + } + + private static class C { + } + + private static class A extends C { + public E objectField = new E(); + } + + private static class B extends A { + } + + private static class D extends C { + public int neverAccessedField = 0x12345678; + + } + + private static class E { + public int intField; + } + +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/gcbarriers/TestArrayCopyWithLargeObjectAlignment.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/gcbarriers/TestArrayCopyWithLargeObjectAlignment.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/gcbarriers/TestArrayCopyWithLargeObjectAlignment.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/gcbarriers/TestArrayCopyWithLargeObjectAlignment.java 2024-01-16 16:19:00.000000000 +0000 @@ -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. + */ +package compiler.gcbarriers; + +import java.util.Arrays; + +/** + * @test + * @bug 8312749 + * @summary Test that, when using a larger object alignment, ZGC arraycopy + * barriers are only applied to actual OOPs, and not to object + * alignment padding words. + * @requires vm.gc.ZGenerational + * @run main/othervm -Xbatch -XX:-TieredCompilation + * -XX:CompileOnly=compiler.gcbarriers.TestArrayCopyWithLargeObjectAlignment::* + * -XX:ObjectAlignmentInBytes=16 + * -XX:+UseZGC -XX:+ZGenerational + * compiler.gcbarriers.TestArrayCopyWithLargeObjectAlignment + */ + +public class TestArrayCopyWithLargeObjectAlignment { + + static Object[] doCopyOf(Object[] array) { + return Arrays.copyOf(array, array.length); + } + + static Object[] doClone(Object[] array) { + return array.clone(); + } + + public static void main(String[] args) { + for (int i = 0; i < 10_000; i++) { + // This test allocates an array 'a', copies it into a new array 'b' + // using Arrays.copyOf, and clones 'b' into yet another array. For + // ObjectAlignmentInBytes=16, the intrinsic implementation of + // Arrays.copyOf leaves the object alignment padding word "b[1]" + // untouched, preserving the badHeapWordVal value '0xbaadbabe'. The + // test checks that this padding word is not processed as a valid + // OOP by the ZGC arraycopy stub underlying the intrinsic + // implementation of Object.clone. Allocating b using the intrinsic + // implementation of Arrays.copyOf is key to reproducing the issue + // because, unlike regular (fast or slow) array allocation, + // Arrays.copyOf does not zero-clear the padding word. + Object[] a = {new Object()}; + Object[] b = doCopyOf(a); + doClone(b); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -35,9 +35,9 @@ * * @build compiler.jvmci.common.JVMCIHelpers * compiler.jvmci.events.JvmciShutdownEventListener - * @run driver jdk.test.lib.FileInstaller ./JvmciShutdownEventTest.config + * @run main/othervm jdk.test.lib.FileInstaller ./JvmciShutdownEventTest.config * ./META-INF/services/jdk.vm.ci.services.JVMCIServiceLocator - * @run driver jdk.test.lib.helpers.ClassFileInstaller + * @run main/othervm jdk.test.lib.helpers.ClassFileInstaller * compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler * compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory * compiler.jvmci.common.JVMCIHelpers$EmptyCompilationRequestResult diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -31,7 +31,7 @@ * java.base/jdk.internal.misc * @library /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src * @build jdk.vm.ci.hotspot.test.DummyClass - * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.vm.ci.hotspot.test.DummyClass + * @run main/othervm jdk.test.lib.helpers.ClassFileInstaller jdk.vm.ci.hotspot.test.DummyClass * @run testng/othervm/timeout=300 -Xbootclasspath/a:. * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI * -XX:-UseJVMCICompiler jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/jvmci/meta/StableFieldTest.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/jvmci/meta/StableFieldTest.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/jvmci/meta/StableFieldTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/jvmci/meta/StableFieldTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -33,7 +33,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * * @compile StableFieldTest.java - * @run driver jdk.test.lib.helpers.ClassFileInstaller compiler.jvmci.meta.StableFieldTest + * @run main/othervm jdk.test.lib.helpers.ClassFileInstaller compiler.jvmci.meta.StableFieldTest * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler -Xbootclasspath/a:. compiler.jvmci.meta.StableFieldTest */ diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/locks/TestUnlockOSR.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/locks/TestUnlockOSR.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/locks/TestUnlockOSR.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/locks/TestUnlockOSR.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8316746 + * @summary During OSR, locks get transferred from interpreter frame. + * Check that unlocking 2 such locks works in the OSR compiled nmethod. + * Some platforms verify that the unlocking happens in the corrent order. + * + * @run main/othervm -Xbatch TestUnlockOSR + */ + +public class TestUnlockOSR { + static void test_method(Object a, Object b, int limit) { + synchronized(a) { // allocate space for monitors + synchronized(b) { + } + } // free space to test allocation in reused space + synchronized(a) { // reuse the space + synchronized(b) { + for (int i = 0; i < limit; i++) {} + } + } + } + + public static void main(String[] args) { + Object a = new TestUnlockOSR(), + b = new TestUnlockOSR(); + // avoid uncommon trap before last unlocks + for (int i = 0; i < 100; i++) { test_method(a, b, 0); } + // trigger OSR + test_method(a, b, 100000); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestBadControlAfterPreMainPost.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestBadControlAfterPreMainPost.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestBadControlAfterPreMainPost.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestBadControlAfterPreMainPost.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8315920 + * @summary C2: "control input must dominate current control" assert failure + * @requires vm.compiler2.enabled + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseLoopPredicate -XX:-DoEscapeAnalysis TestBadControlAfterPreMainPost + */ + +public class TestBadControlAfterPreMainPost { + private static volatile int volatileField; + + public static void main(String[] args) { + int[] array2 = new int[100]; + for (int i = 0; i < 20_000; i++) { + test(1, array2); + } + } + + private static int test(int j, int[] array2) { + int[] array = new int[10]; + array[j] = 42; + float f = 1; + for (int i = 0; i < 100; i++) { + for (int k = 0; k < 10; k++) { + } + f = f * 2; + } + int v = array[0]; + int i = 0; + do { + synchronized (new Object()) { + } + array2[i + v] = 42; + i++; + } while (i < 100); + return (int)f; + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestSinkingMoreThan2AddPNodes.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestSinkingMoreThan2AddPNodes.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestSinkingMoreThan2AddPNodes.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestSinkingMoreThan2AddPNodes.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8315377 + * @requires vm.compiler2.enabled + * @summary C2: assert(u->find_out_with(Op_AddP) == nullptr) failed: more than 2 chained AddP nodes? + * @library /test/lib + * @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileOnly=TestSinkingMoreThan2AddPNodes::test TestSinkingMoreThan2AddPNodes + * + */ + +import jdk.test.lib.Utils; + +public class TestSinkingMoreThan2AddPNodes { + public static void main(String[] strArr) throws Exception { + Thread t = new Thread(new Runnable() { + public void run() { + test(); + } + }); + t.setDaemon(true); + t.start(); + Thread.sleep(Utils.adjustTimeout(500)); + } + + static void test() { + double dArr[] = new double[10]; + int i4 = 5, i11, i12 = 2, iArr[] = new int[400]; + long l1; + byte by1 = 0; + short s1 = 8; + + for (int i = 0; i < iArr.length; i++) { + iArr[i] = (i % 2 == 0) ? 23 : 34; + } + + for (i11 = 10; i11 > 9; ) { + l1 = 1; + do { + try { + i4 = 6 % i4; + i12 = iArr[(int) l1]; + } catch (ArithmeticException a_e) { + } + by1 += 8; + iArr = iArr; + } while (++l1 < 11); + } + + long meth_res = i12; + } +} + diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestSinkingNodesCausesLongCompilation.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestSinkingNodesCausesLongCompilation.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestSinkingNodesCausesLongCompilation.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestSinkingNodesCausesLongCompilation.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8308103 + * @summary Massive (up to ~30x) increase in C2 compilation time since JDK 17 + * @run main/othervm -Xcomp -XX:CompileOnly=TestSinkingNodesCausesLongCompilation::mainTest -XX:+UnlockDiagnosticVMOptions + * -XX:RepeatCompilation=30 TestSinkingNodesCausesLongCompilation + */ + +public class TestSinkingNodesCausesLongCompilation { + public static final int N = 400; + public static int iFld=41489; + + public void mainTest(String[] strArr1) { + int i9=-13, i10=-248, i11=-4, i13=33, i15=-171, i18=-58, iArr2[]=new int[N]; + + for (i9 = 7; i9 < 256; i9++) { + i11 = 1; + do { + } while (++i11 < 101); + } + for (int i14 : iArr2) { + for (i15 = 63; 0 < i15; i15 -= 2) { + i10 *= i13; + i10 >>= i14; + } + for (i18 = 2; 63 > i18; i18++) { + i10 = iFld; + iArr2[i18] |= i11; + } + } + System.out.println("i9 = " + i9); + } + + public static void main(String[] strArr) { + TestSinkingNodesCausesLongCompilation _instance = new TestSinkingNodesCausesLongCompilation(); + for (int i = 0; i < 10; i++) { + _instance.mainTest(strArr); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestSunkNodeMissingCastAssert.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestSunkNodeMissingCastAssert.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/TestSunkNodeMissingCastAssert.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/TestSunkNodeMissingCastAssert.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8312440 + * @summary assert(cast != nullptr) failed: must have added a cast to pin the node + * @run main/othervm -XX:-BackgroundCompilation TestSunkNodeMissingCastAssert + */ + + +public class TestSunkNodeMissingCastAssert { + private static int N = 500; + private static int ia[] = new int[N]; + private static volatile int ib[] = new int[N]; + + private static void test() { + for (int k = 1; k < 200; k++) + switch (k % 5) { + case 0: + ia[k - 1] -= 15; + case 2: + for (int m = 0; m < 1000; m++); + case 3: + ib[k - 1] <<= 5; + case 4: + ib[k + 1] <<= 3; + } + } + + public static void main(String[] args) { + for (int i = 0; i < 20000; i++) { + test(); + } + } +} + diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * 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 + * @requires vm.compiler2.enabled + * @bug 8316679 + * @summary In SuperWord::output, LoadVector can be moved before StoreVector, but only if it is proven to be safe. + * @key randomness + * @library /test/lib + * @run main/othervm -XX:CompileCommand=compileonly,compiler.loopopts.superword.TestMovingLoadBeforeStore::test* + * -Xbatch -XX:LoopUnrollLimit=100 + * -XX:+UnlockDiagnosticVMOptions -XX:+StressLCM + * compiler.loopopts.superword.TestMovingLoadBeforeStore + */ + +package compiler.loopopts.superword; +import java.util.Random; +import jdk.test.lib.Utils; + +public class TestMovingLoadBeforeStore { + static int RANGE = 1024*64; + + private static final Random random = Utils.getRandomInstance(); + + public static void main(String[] strArr) { + byte a[] = new byte[RANGE]; + for (int i = 0; i < 100; i++) { + for (int j = 0; j < a.length; j++) { + a[j] = (byte)random.nextInt(); + } + byte[] a_ref = a.clone(); + byte[] a_res = a.clone(); + ref1(a_ref, a_ref, i % 2); + test1(a_res, a_res, i % 2); + verify("a in test1", a_ref, a_res, a); + } + } + + static void verify(String name, byte[] ref, byte[] res, byte[] orig) { + boolean fail = false; + for (int j = 0; j < ref.length; j++) { + if (ref[j] != res[j]) { + System.out.println("Wrong: " + j + ":" + ref[j] + " vs " + res[j] + " from " + orig[j]); + fail = true; + } + } + if (fail) { + throw new RuntimeException("wrong result for array " + name); + } + } + + static void test1(byte[] a, byte[] b, int inv) { + for (int i = 0; i < RANGE-4; i+=4) { + a[i + 0]++; + a[i + 1]++; + a[i + 2]++; + a[i + 3]++; + b[inv + i + 0]++; + b[inv + i + 1]++; + b[inv + i + 2]++; + b[inv + i + 3]++; + } + } + + static void ref1(byte[] a, byte[] b, int inv) { + for (int i = 0; i < RANGE-4; i+=4) { + a[i + 0]++; + a[i + 1]++; + a[i + 2]++; + a[i + 3]++; + b[inv + i + 0]++; + b[inv + i + 1]++; + b[inv + i + 2]++; + b[inv + i + 3]++; + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopstripmining/TestBrokenEmptyLoopLogic.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopstripmining/TestBrokenEmptyLoopLogic.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/loopstripmining/TestBrokenEmptyLoopLogic.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/loopstripmining/TestBrokenEmptyLoopLogic.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8315088 + * @requires vm.compiler2.enabled + * @summary C2: assert(wq.size() - before == EMPTY_LOOP_SIZE) failed: expect the EMPTY_LOOP_SIZE nodes of this body if empty + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,TestBrokenEmptyLoopLogic::* -XX:-TieredCompilation TestBrokenEmptyLoopLogic + * + */ + +public class TestBrokenEmptyLoopLogic { + + public static void main(String[] strArr) { + for (int i = 0; i < 10000; i++) { + test(); + } + } + + static void test() { + int i8 = 209, i = 1, i12 = 1; + while (++i < 8) { + for (int j = 5; j > 1; j -= 2) { + i12 = 1; + do { + } while (++i12 < 3); + } + for (int j = i; j < 5; ++j) { + i8 += i12; + } + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/rangechecks/TestLongRCWithLoopIncr.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/rangechecks/TestLongRCWithLoopIncr.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/rangechecks/TestLongRCWithLoopIncr.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/rangechecks/TestLongRCWithLoopIncr.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8314580 + * @summary PhaseIdealLoop::transform_long_range_checks fails with assert "was tested before" + * @run main/othervm -XX:-BackgroundCompilation TestLongRCWithLoopIncr + * + */ + +import java.util.Objects; + +public class TestLongRCWithLoopIncr { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(1001); + } + } + + private static void test(long length) { + for (long i = 0; i < 1000; i++) { + Objects.checkIndex(i + 1, length); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/regalloc/TestNodeRegArrayOverflow.java openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/regalloc/TestNodeRegArrayOverflow.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/compiler/regalloc/TestNodeRegArrayOverflow.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/compiler/regalloc/TestNodeRegArrayOverflow.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,599 @@ +/* + * 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 compiler.regalloc; + +/** + * @test + * @bug 8317507 + * @summary Test that C2's PhaseRegAlloc::_node_regs (a post-register-allocation + * mapping from machine nodes to assigned registers) does not overflow + * in the face of a program with a high-density of CISC spilling + * candidate nodes. + * @run main/othervm -Xcomp -XX:CompileOnly=compiler.regalloc.TestNodeRegArrayOverflow::testWithCompilerUnrolling + -XX:CompileCommand=dontinline,compiler.regalloc.TestNodeRegArrayOverflow::dontInline + compiler.regalloc.TestNodeRegArrayOverflow compiler + * @run main/othervm -Xcomp -XX:CompileOnly=compiler.regalloc.TestNodeRegArrayOverflow::testWithManualUnrolling + -XX:CompileCommand=dontinline,compiler.regalloc.TestNodeRegArrayOverflow::dontInline + compiler.regalloc.TestNodeRegArrayOverflow manual + */ + +public class TestNodeRegArrayOverflow { + + static int dontInline() { + return 0; + } + + static float testWithCompilerUnrolling(float inc) { + int i = 0, j = 0; + // This non-inlined method call causes 'inc' to be spilled. + float f = dontInline(); + // This two-level reduction loop is unrolled 512 times, which is + // requested by the SLP-specific unrolling analysis, but not vectorized. + // Because 'inc' is spilled, each of the unrolled AddF nodes is + // CISC-spill converted (PhaseChaitin::fixup_spills()). Before the fix, + // this causes the unique node index counter (Compile::_unique) to grow + // beyond the size of the node register array + // (PhaseRegAlloc::_node_regs), and leads to overflow when accessed for + // nodes that are created later (e.g. during the peephole phase). + while (i++ < 128) { + for (j = 0; j < 16; j++) { + f += inc; + } + } + return f; + } + + // This test reproduces the same failure as 'testWithCompilerUnrolling' + // without relying on loop transformations. + static float testWithManualUnrolling(float inc) { + int i = 0, j = 0; + float f = dontInline(); + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + f += inc; + return f; + } + + public static void main(String[] args) { + switch (args[0]) { + case "compiler": + testWithCompilerUnrolling(0); + break; + case "manual": + testWithManualUnrolling(0); + break; + default: + throw new IllegalArgumentException("Invalid mode: " + args[0]); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java openjdk-21-21.0.2+13/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java 2024-01-16 16:19:00.000000000 +0000 @@ -77,6 +77,7 @@ Common.logNewTestCase("Test print_container_info()"); DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo").addJavaOpts("-XshowSettings:system"); + opts.addDockerOpts("--cpus", "4"); // Avoid OOM kill on many-core systems opts.addDockerOpts("--memory", dockerMemLimit, "--memory-swappiness", "0", "--memory-swap", dockerSwapMemLimit); Common.addWhiteBoxOpts(opts); @@ -104,6 +105,7 @@ String swappiness, String expectedSwap) throws Exception { Common.logNewTestCase("Check OperatingSystemMXBean"); DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean") + .addDockerOpts("--cpus", "4") // Avoid OOM kill on many-core systems .addDockerOpts( "--memory", memoryAllocation, "--memory-swappiness", swappiness, diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java 2024-01-16 16:19:00.000000000 +0000 @@ -58,7 +58,13 @@ // Do this once here. // Scan for Metaspace update notices as part of the GC log, e.g. in this form: // [gc,metaspace ] GC(0) Metaspace: 11895K(14208K)->11895K(14208K) NonClass: 10552K(12544K)->10552K(12544K) Class: 1343K(1664K)->1343K(1664K) - metaSpaceRegexp = Pattern.compile(".*Metaspace: ([0-9]+).*->([0-9]+).*"); + // This regex has to be up-to-date with the format used in hotspot to print metaspace change. + final String NUM_K = "\\d+K"; + final String GP_NUM_K = "(\\d+)K"; + final String BR_NUM_K = "\\(" + NUM_K + "\\)"; + final String SIZE_CHG = NUM_K + BR_NUM_K + "->" + NUM_K + BR_NUM_K; + metaSpaceRegexp = Pattern.compile(".* Metaspace: " + GP_NUM_K + BR_NUM_K + "->" + GP_NUM_K + BR_NUM_K + + "( NonClass: " + SIZE_CHG + " Class: " + SIZE_CHG + ")?$"); } public static void main(String[] args) throws Exception { diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java 2024-01-16 16:19:00.000000000 +0000 @@ -54,7 +54,6 @@ new String[] { "ShenandoahSATBBarrier", "ShenandoahIUBarrier" }, new String[] { "ShenandoahCASBarrier" }, new String[] { "ShenandoahCloneBarrier" }, - new String[] { "ShenandoahNMethodBarrier" }, new String[] { "ShenandoahStackWatermarkBarrier" } }; diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java 2024-01-16 16:19:00.000000000 +0000 @@ -42,7 +42,6 @@ "ShenandoahSATBBarrier", "ShenandoahCASBarrier", "ShenandoahCloneBarrier", - "ShenandoahNMethodBarrier", "ShenandoahStackWatermarkBarrier", }; String[] iu = { @@ -50,7 +49,6 @@ "ShenandoahIUBarrier", "ShenandoahCASBarrier", "ShenandoahCloneBarrier", - "ShenandoahNMethodBarrier", "ShenandoahStackWatermarkBarrier", }; diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java 2024-01-16 16:19:00.000000000 +0000 @@ -24,14 +24,41 @@ package gc.stress; /* - * @test TestStressG1Humongous + * @test * @key stress * @summary Stress G1 by humongous allocations in situation near OOM * @requires vm.gc.G1 * @requires !vm.flightRecorder * @library /test/lib * @modules java.base/jdk.internal.misc - * @run driver/timeout=1300 gc.stress.TestStressG1Humongous + * @run driver/timeout=180 gc.stress.TestStressG1Humongous 4 3 1.1 120 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires !vm.flightRecorder + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @run driver/timeout=180 gc.stress.TestStressG1Humongous 16 5 2.1 120 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires !vm.flightRecorder + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @run driver/timeout=180 gc.stress.TestStressG1Humongous 32 4 0.6 120 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires !vm.flightRecorder + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @run driver/timeout=900 gc.stress.TestStressG1Humongous 1 7 0.6 600 */ import java.util.ArrayList; @@ -48,17 +75,19 @@ public class TestStressG1Humongous{ public static void main(String[] args) throws Exception { + if (args.length != 4) { + throw new IllegalArgumentException("Test expects 4 arguments"); + } + // Limit heap size on 32-bit platforms int heapSize = Platform.is32bit() ? 512 : 1024; - // Heap size, region size, threads, humongous size, timeout - run(heapSize, 4, 3, 1.1, 120); - run(heapSize, 16, 5, 2.1, 120); - run(heapSize, 32, 4, 0.6, 120); - run(heapSize, 1, 7, 0.6, 600); - } - private static void run(int heapSize, int regionSize, int threads, double humongousSize, int timeout) - throws Exception { + // Region size, threads, humongous size, and timeout passed as @run arguments + int regionSize = Integer.parseInt(args[0]); + int threads = Integer.parseInt(args[1]); + double humongousSize = Double.parseDouble(args[2]); + int timeout = Integer.parseInt(args[3]); + ArrayList options = new ArrayList<>(); Collections.addAll(options, Utils.getTestJavaOpts()); Collections.addAll(options, diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/stress/TestStressIHOPMultiThread.java openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/stress/TestStressIHOPMultiThread.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/stress/TestStressIHOPMultiThread.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/stress/TestStressIHOPMultiThread.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -24,7 +24,7 @@ package gc.stress; /* - * @test TestStressIHOPMultiThread + * @test * @bug 8148397 * @key stress * @summary Stress test for IHOP @@ -34,21 +34,41 @@ * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread1.log * -Dtimeout=2 -DheapUsageMinBound=30 -DheapUsageMaxBound=80 * -Dthreads=2 gc.stress.TestStressIHOPMultiThread + */ + +/* + * @test + * @requires vm.gc.G1 * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1 * -XX:+UseG1GC -XX:G1HeapRegionSize=2m -XX:+G1UseAdaptiveIHOP * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread2.log * -Dtimeout=2 -DheapUsageMinBound=60 -DheapUsageMaxBound=90 * -Dthreads=3 gc.stress.TestStressIHOPMultiThread + */ + +/* + * @test + * @requires vm.gc.G1 * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1 * -XX:+UseG1GC -XX:G1HeapRegionSize=4m -XX:-G1UseAdaptiveIHOP * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread3.log * -Dtimeout=2 -DheapUsageMinBound=40 -DheapUsageMaxBound=90 * -Dthreads=5 gc.stress.TestStressIHOPMultiThread + */ + +/* + * @test + * @requires vm.gc.G1 * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1 * -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:+G1UseAdaptiveIHOP * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread4.log * -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90 * -Dthreads=10 gc.stress.TestStressIHOPMultiThread + */ + +/* + * @test + * @requires vm.gc.G1 * @run main/othervm/timeout=200 -Xmx512m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1 * -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:+G1UseAdaptiveIHOP * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread5.log diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/stress/TestStressRSetCoarsening.java openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/stress/TestStressRSetCoarsening.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/gc/stress/TestStressRSetCoarsening.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/gc/stress/TestStressRSetCoarsening.java 2024-01-16 16:19:00.000000000 +0000 @@ -27,13 +27,12 @@ import jdk.test.whitebox.WhiteBox; /* - * @test TestStressRSetCoarsening.java + * @test * @key stress * @bug 8146984 8147087 * @requires vm.gc.G1 * @requires os.maxMemory > 3G * @requires vm.opt.MaxGCPauseMillis == "null" - * * @summary Stress G1 Remembered Set by creating a lot of cross region links * @modules java.base/jdk.internal.misc * @library /test/lib @@ -42,27 +41,82 @@ * @run main/othervm/timeout=300 * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000 - * -Xmx500m -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 1 0 300 + * -Xmx500m -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 1 0 300 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires os.maxMemory > 3G + * @requires vm.opt.MaxGCPauseMillis == "null" + * @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/timeout=300 * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000 - * -Xmx500m -XX:G1HeapRegionSize=8m gc.stress.TestStressRSetCoarsening 1 10 300 + * -Xmx500m -XX:G1HeapRegionSize=8m gc.stress.TestStressRSetCoarsening 1 10 300 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires os.maxMemory > 3G + * @requires vm.opt.MaxGCPauseMillis == "null" + * @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/timeout=300 * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000 * -Xmx500m -XX:G1HeapRegionSize=32m gc.stress.TestStressRSetCoarsening 42 10 300 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires os.maxMemory > 3G + * @requires vm.opt.MaxGCPauseMillis == "null" + * @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/timeout=300 * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000 - * -Xmx500m -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 2 0 300 + * -Xmx500m -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 2 0 300 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires os.maxMemory > 3G + * @requires vm.opt.MaxGCPauseMillis == "null" + * @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/timeout=1800 * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000 - * -Xmx1G -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 500 0 1800 + * -Xmx1G -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 500 0 1800 + */ + +/* + * @test + * @requires vm.gc.G1 + * @requires os.maxMemory > 3G + * @requires vm.opt.MaxGCPauseMillis == "null" + * @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/timeout=1800 * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000 - * -Xmx1G -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 10 10 1800 + * -Xmx1G -XX:G1HeapRegionSize=1m gc.stress.TestStressRSetCoarsening 10 10 1800 */ /** @@ -95,7 +149,7 @@ } int objectsPerRegion = Integer.parseInt(args[0]); // 1 means humongous int regsToRefresh = Integer.parseInt(args[1]); // 0 means no regions to refresh at the end of cycle - int timeout = Integer.parseInt(args[2]); // in seconds, test should stop working eariler + int timeout = Integer.parseInt(args[2]); // in seconds, test should stop working earlier new TestStressRSetCoarsening(objectsPerRegion, regsToRefresh, timeout).go(); } diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/ErrorHandling/TestSymbolsInHsErrFile.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/ErrorHandling/TestSymbolsInHsErrFile.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/ErrorHandling/TestSymbolsInHsErrFile.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/ErrorHandling/TestSymbolsInHsErrFile.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 symbolsHsErr + * @summary Test that function names are present in native frames of hs-err file as a proof that symbols are available. + * @library /test/lib + * @requires vm.flagless + * @requires vm.debug + * @requires os.family == "windows" + * @modules java.base/jdk.internal.misc + * java.management + * @run driver TestSymbolsInHsErrFile + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class TestSymbolsInHsErrFile { + + public static void main(String[] args) throws Exception { + + // Start a jvm and cause a SIGSEGV / ACCESS_VIOLATION + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-Xmx100M", + "-XX:-CreateCoredumpOnCrash", + "-XX:ErrorHandlerTest=14", + "-version"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotHaveExitValue(0); + + // Verify that the hs_err problematic frame contains a function name that points to origin of the crash; + // on Windows/MSVC, if symbols are present and loaded, we should see a ref to either 'crash_with_segfault' + // 'VMError::controlled_crash' depending on whether the compile optimizations (i.e. crash_with_segfault + // was inlined or not): + // # Problematic frame: + // # V [jvm.dll+0x.....] crash_with_segfault+0x10 + // or + // # V [jvm.dll+0x.....] VMError::controlled_crash+0x99 + // + // If symbols could not be loaded, however, then the frame will contain not function name at all, i.e. + // # Problematic frame: + // # V [jvm.dll+0x.....] + // NB: this is not true for other OS/Compilers, where the functions names are present even with no symbols, + // hence this test being restricted to Windows only. + output.shouldMatch(("# V \\[jvm.dll.*\\].*(crash_with_segfault|controlled_crash).*")); + + } + +} + + diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/InvocationTests/shared/AbstractGenerator.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/InvocationTests/shared/AbstractGenerator.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/InvocationTests/shared/AbstractGenerator.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/InvocationTests/shared/AbstractGenerator.java 2024-01-16 16:19:00.000000000 +0000 @@ -35,6 +35,7 @@ protected final boolean dumpClasses; protected final boolean executeTests; private static int testNum = 0; + private static int classesBeforeGC = 0; protected AbstractGenerator(String[] args) { List params = new ArrayList(Arrays.asList(args)); @@ -96,6 +97,14 @@ testNum++; + // Every N-th classes, force a GC to kick out the loaded classes from previous tests. + // Different tests come in with different number of classes, so testNum is not reliable. + classesBeforeGC -= classes.size(); + if (classesBeforeGC <= 0) { + System.gc(); + classesBeforeGC = 3000; + } + String caseDescription = String.format("%4d| %s", testNum, description); // Create test executor for a single case diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/NMT/SummaryDiffThreadCount.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/NMT/SummaryDiffThreadCount.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/NMT/SummaryDiffThreadCount.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/NMT/SummaryDiffThreadCount.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 run NMT baseline, create threads and verify output from summary.diff + * @author Evgeny Ignatenko + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary SummaryDiffThreadCount + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.JDKToolFinder; + +public class SummaryDiffThreadCount { + public static void main(String args[]) throws Exception { + ProcessBuilder pb = new ProcessBuilder(); + OutputAnalyzer output; + // Grab my own PID. + String pid = Long.toString(ProcessTools.getProcessId()); + + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=true"}); + pb.start().waitFor(); + + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Baseline taken"); + + // Creating 10 threads. + for (int i = 0; i < 10; i++) { + new Thread(()-> { + while (true) { continue; } + }).start(); + } + + // Running "jcmd VM.native_memory summary.diff" and checking for five new threads reported. + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary.diff"}); + output = new OutputAnalyzer(pb.start()); + + // Trailing '+' is needed to check that NMT now reports that now we have more threads than it + // was during the baseline. + output.shouldMatch("thread #\\d+ \\+"); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java 2024-01-16 16:19:00.000000000 +0000 @@ -24,12 +24,15 @@ /* * @test * @summary Test merging of committed virtual memory and that we track it correctly + * @comment needs to be executed with -Xint (or, alternatively, -Xcomp -Xbatch) since it relies on comparing + * NMT call stacks, and we must make sure that all functions on the stack that NMT sees are either compiled + * from the get-go or stay always interpreted. * @library /test/lib * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitMerge + * @run main/othervm -Xbootclasspath/a:. -Xint -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitMerge * */ diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java 2024-01-16 16:19:00.000000000 +0000 @@ -34,6 +34,7 @@ /* * @test * @summary Test AlwaysPreTouchThreadStacks + * @requires os.family != "aix" * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -259,21 +259,36 @@ } } + static final String keyTool = JDKToolFinder.getJDKTool("keytool"); + static final String jarSigner = JDKToolFinder.getJDKTool("jarsigner"); - public static void signJar() throws Exception { - String keyTool = JDKToolFinder.getJDKTool("keytool"); - String jarSigner = JDKToolFinder.getJDKTool("jarsigner"); + public static void signJarWithDisabledAlgorithm(String jarName) throws Exception { + String keyName = "key_with_disabled_alg"; + executeProcess(keyTool, + "-genkey", "-keystore", "./keystore", "-alias", keyName, + "-storepass", "abc123", "-keypass", "abc123", "-keyalg", "dsa", + "-sigalg", "SHA1withDSA", "-keysize", "512", "-dname", "CN=jvmtest2") + .shouldHaveExitValue(0); + doSigning(jarName, keyName); + } + + public static void signJar(String jarName) throws Exception { + String keyName = "mykey"; executeProcess(keyTool, - "-genkey", "-keystore", "./keystore", "-alias", "mykey", + "-genkey", "-keystore", "./keystore", "-alias", keyName, "-storepass", "abc123", "-keypass", "abc123", "-keyalg", "dsa", "-dname", "CN=jvmtest") .shouldHaveExitValue(0); + doSigning(jarName, keyName); + } + + private static void doSigning(String jarName, String keyName) throws Exception { executeProcess(jarSigner, "-keystore", "./keystore", "-storepass", "abc123", "-keypass", - "abc123", "-signedjar", getJarFilePath("signed_hello"), - getJarFilePath("hello"), "mykey") + "abc123", "-signedjar", getJarFilePath("signed_" + jarName), + getJarFilePath(jarName), keyName) .shouldHaveExitValue(0); } diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java 2024-01-16 16:19:00.000000000 +0000 @@ -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. + * + */ + +/* + * @test + * @bug 8312434 + * @summary A jar file containing classes in the same package. Sign the jar file with + * a disabled algorithm. The jar will be treated as unsigned. + * Dump only one class into the CDS archive. During runtime, load the class + * stored in the archive and then load another class not from the archive + * but from the same pacakge. Loading of the second class should not result + * in sealing violation. + * + * @requires vm.cds + * @library /test/lib + * @compile test-classes/GenericTestApp.java test-classes/pkg/ClassInPackage.java test-classes/C2.java + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox + * @run driver SealingViolation + */ + +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class SealingViolation { + public static void main(String[] args) throws Exception { + String[] classList = {"pkg/ClassInPackage"}; + String appJar = ClassFileInstaller.writeJar("pkg-classes-sealed.jar", + ClassFileInstaller.Manifest.fromSourceFile("test-classes/pkg/package_seal.mf"), + "GenericTestApp", "pkg/ClassInPackage", "pkg/C2"); + + JarBuilder.signJarWithDisabledAlgorithm("pkg-classes-sealed"); + String signedJar = TestCommon.getTestJar("pkg-classes-sealed.jar"); + + // GenericTestApp requires WhiteBox + String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); + String bootclasspath = "-Xbootclasspath/a:" + wbJar; + + OutputAnalyzer output = TestCommon.dump(signedJar, classList, bootclasspath, + "-Xlog:cds+class=debug"); + output.shouldMatch("cds.class.*klasses.*app pkg.ClassInPackage") + .shouldHaveExitValue(0); + + output = TestCommon.exec(signedJar, "-Xlog:cds=debug,class+load", + bootclasspath, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "GenericTestApp", + "assertShared:pkg.ClassInPackage", + "assertNotShared:pkg.C2"); + output.shouldHaveExitValue(0); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java 2024-01-16 16:19:00.000000000 +0000 @@ -38,7 +38,7 @@ public class SignedJar { public static void main(String[] args) throws Exception { String unsignedJar = JarBuilder.getOrCreateHelloJar(); - JarBuilder.signJar(); + JarBuilder.signJar("hello"); // Test class exists in signed JAR String signedJar = TestCommon.getTestJar("signed_hello.jar"); diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Created-By: 1.9.0-internal (Oracle Corporation) + +Name: pkg/ +Sealed: true + diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/jni/terminatedThread/libterminatedThread.c openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/jni/terminatedThread/libterminatedThread.c --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/jni/terminatedThread/libterminatedThread.c 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/jni/terminatedThread/libterminatedThread.c 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, 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 @@ -29,6 +29,8 @@ #include "jni.h" +#define STACK_SIZE 0x100000 + JavaVM* jvm; jobject nativeThread; @@ -79,11 +81,14 @@ fprintf(stderr, "Test ERROR. Can't extract JavaVM: %d\n", res); exit(1); } - - if ((res = pthread_create(&thread, NULL, thread_start, NULL)) != 0) { + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, STACK_SIZE); + if ((res = pthread_create(&thread, &attr, thread_start, NULL)) != 0) { fprintf(stderr, "TEST ERROR: pthread_create failed: %s (%d)\n", strerror(res), res); exit(1); } + pthread_attr_destroy(&attr); if ((res = pthread_join(thread, NULL)) != 0) { fprintf(stderr, "TEST ERROR: pthread_join failed: %s (%d)\n", strerror(res), res); diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/lockStack/TestStackWalk.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/lockStack/TestStackWalk.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/lockStack/TestStackWalk.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/lockStack/TestStackWalk.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * 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 8317262 + * @library /testlibrary /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:+HandshakeALot -XX:GuaranteedSafepointInterval=1 TestStackWalk + */ + +import jvmti.JVMTIUtils; +import jdk.test.lib.Asserts; +import jdk.test.whitebox.WhiteBox; +import java.util.concurrent.CountDownLatch; + +public class TestStackWalk { + static Thread worker1; + static Thread worker2; + static volatile boolean done; + static volatile int counter = 0; + static Object lock = new Object(); + + public static void main(String... args) throws Exception { + worker1 = new Thread(() -> syncedWorker()); + worker1.start(); + worker2 = new Thread(() -> syncedWorker()); + worker2.start(); + Thread worker3 = new Thread(() -> stackWalker()); + worker3.start(); + + worker1.join(); + worker2.join(); + worker3.join(); + } + + public static void syncedWorker() { + synchronized (lock) { + while (!done) { + counter++; + } + } + } + + public static void stackWalker() { + // Suspend workers so the one looping waiting for "done" + // doesn't execute the handshake below, increasing the + // chances the VMThread will do it. + suspendWorkers(); + + WhiteBox wb = WhiteBox.getWhiteBox(); + long end = System.currentTimeMillis() + 20000; + while (end > System.currentTimeMillis()) { + wb.handshakeWalkStack(worker1, false /* all_threads */); + wb.handshakeWalkStack(worker2, false /* all_threads */); + } + + resumeWorkers(); + done = true; + } + + static void suspendWorkers() { + JVMTIUtils.suspendThread(worker1); + JVMTIUtils.suspendThread(worker2); + } + + static void resumeWorkers() { + JVMTIUtils.resumeThread(worker1); + JVMTIUtils.resumeThread(worker2); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/locking/TestOutOfOrderUnlocking.jasm openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/locking/TestOutOfOrderUnlocking.jasm --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/locking/TestOutOfOrderUnlocking.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/locking/TestOutOfOrderUnlocking.jasm 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test id=int + * @summary Check that monitorenter A; monitorenter B; monitorexit A; monitorexit B; works + * @compile TestOutOfOrderUnlocking.jasm + * @run main/othervm -Xint TestOutOfOrderUnlocking + */ +/* + * @test id=comp + * @summary Check that monitorenter A; monitorenter B; monitorexit A; monitorexit B; works, with -Xcomp + * @compile TestOutOfOrderUnlocking.jasm + * @run main/othervm -Xcomp TestOutOfOrderUnlocking + */ + +super public class TestOutOfOrderUnlocking version 64:0 { + + public static Method main:"([Ljava/lang/String;)V" stack 2 locals 4 { + new class java/lang/Object; + dup; + invokespecial Method java/lang/Object."":"()V"; + astore_1; + new class java/lang/Object; + dup; + invokespecial Method java/lang/Object."":"()V"; + astore_2; + aload_1; + monitorenter; + aload_2; + monitorenter; + aload_1; + monitorexit; + aload_2; + monitorexit; + return; + } + +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/os/HugePageConfiguration.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/os/HugePageConfiguration.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/os/HugePageConfiguration.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/os/HugePageConfiguration.java 2024-01-16 16:19:00.000000000 +0000 @@ -30,17 +30,46 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +// This class allows us to parse system hugepage config from +// - a) the Operating System (the truth) +// - b) the JVM log (-Xlog:pagesize) +// This is used e.g. in TestHugePageDetection to determine if the JVM detects the correct settings from the OS. class HugePageConfiguration { - Set _staticHugePageSizes; - long _staticDefaultHugePageSize; + public static class StaticHugePageConfig implements Comparable { + public long pageSize = -1; + public long nr_hugepages = -1; + public long nr_overcommit_hugepages = -1; + + @Override + public int hashCode() { + return Objects.hash(pageSize); + } + + @Override + public String toString() { + return "StaticHugePageConfig{" + + "pageSize=" + pageSize + + ", nr_hugepages=" + nr_hugepages + + ", nr_overcommit_hugepages=" + nr_overcommit_hugepages + + '}'; + } + + @Override + public int compareTo(StaticHugePageConfig o) { + return (int) (pageSize - o.pageSize); + } + } + + Set _staticHugePageConfigurations; + long _staticDefaultHugePageSize = -1; - enum THPMode {always, never, madvise, unknown} + enum THPMode {always, never, madvise} THPMode _thpMode; long _thpPageSize; - public Set getStaticHugePageSizes() { - return _staticHugePageSizes; + public Set getStaticHugePageConfigurations() { + return _staticHugePageConfigurations; } public long getStaticDefaultHugePageSize() { @@ -55,8 +84,18 @@ return _thpPageSize; } - public HugePageConfiguration(Set _staticHugePageSizes, long _staticDefaultHugePageSize, THPMode _thpMode, long _thpPageSize) { - this._staticHugePageSizes = _staticHugePageSizes; + // Returns true if the THP support is enabled + public boolean supportsTHP() { + return _thpMode == THPMode.always || _thpMode == THPMode.madvise; + } + + // Returns true if static huge pages are supported (whether or not we have configured the pools) + public boolean supportsStaticHugePages() { + return _staticDefaultHugePageSize > 0 && _staticHugePageConfigurations.size() > 0; + } + + public HugePageConfiguration(Set _staticHugePageConfigurations, long _staticDefaultHugePageSize, THPMode _thpMode, long _thpPageSize) { + this._staticHugePageConfigurations = _staticHugePageConfigurations; this._staticDefaultHugePageSize = _staticDefaultHugePageSize; this._thpMode = _thpMode; this._thpPageSize = _thpPageSize; @@ -65,7 +104,7 @@ @Override public String toString() { return "Configuration{" + - "_staticHugePageSizes=" + _staticHugePageSizes + + "_staticHugePageConfigurations=" + _staticHugePageConfigurations + ", _staticDefaultHugePageSize=" + _staticDefaultHugePageSize + ", _thpMode=" + _thpMode + ", _thpPageSize=" + _thpPageSize + @@ -77,12 +116,8 @@ if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; HugePageConfiguration that = (HugePageConfiguration) o; - return _staticDefaultHugePageSize == that._staticDefaultHugePageSize && _thpPageSize == that._thpPageSize && Objects.equals(_staticHugePageSizes, that._staticHugePageSizes) && _thpMode == that._thpMode; - } - - @Override - public int hashCode() { - return Objects.hash(_staticHugePageSizes, _staticDefaultHugePageSize, _thpMode, _thpPageSize); + return _staticDefaultHugePageSize == that._staticDefaultHugePageSize && _thpPageSize == that._thpPageSize && + Objects.equals(_staticHugePageConfigurations, that._staticHugePageConfigurations) && _thpMode == that._thpMode; } private static long readDefaultHugePageSizeFromOS() { @@ -102,25 +137,36 @@ return 0; } - private static Set readSupportedHugePagesFromOS() { - TreeSet pagesizes = new TreeSet<>(); + private static Set readSupportedHugePagesFromOS() throws IOException { + TreeSet hugePageConfigs = new TreeSet<>(); Pattern pat = Pattern.compile("hugepages-(\\d+)kB"); File[] subdirs = new File("/sys/kernel/mm/hugepages").listFiles(); if (subdirs != null) { - for (File f : subdirs) { - String name = f.getName(); + for (File subdir : subdirs) { + String name = subdir.getName(); Matcher mat = pat.matcher(name); if (mat.matches()) { - long pagesize = Long.parseLong(mat.group(1)) * 1024; - pagesizes.add(pagesize); + StaticHugePageConfig config = new StaticHugePageConfig(); + config.pageSize = Long.parseLong(mat.group(1)) * 1024; + try (FileReader fr = new FileReader(subdir.getAbsolutePath() + "/nr_hugepages"); + BufferedReader reader = new BufferedReader(fr)) { + String s = reader.readLine(); + config.nr_hugepages = Long.parseLong(s); + } + try (FileReader fr = new FileReader(subdir.getAbsolutePath() + "/nr_overcommit_hugepages"); + BufferedReader reader = new BufferedReader(fr)) { + String s = reader.readLine(); + config.nr_overcommit_hugepages = Long.parseLong(s); + } + hugePageConfigs.add(config); } } } - return pagesizes; + return hugePageConfigs; } private static THPMode readTHPModeFromOS() { - THPMode mode = THPMode.unknown; + THPMode mode = THPMode.never; String file = "/sys/kernel/mm/transparent_hugepage/enabled"; try (FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr)) { @@ -136,7 +182,8 @@ } } catch (IOException e) { System.out.println("Failed to read " + file); - mode = THPMode.unknown; + // Happens when the kernel is not built to support THPs. + mode = THPMode.never; } return mode; } @@ -148,19 +195,19 @@ BufferedReader reader = new BufferedReader(fr)) { String s = reader.readLine(); pagesize = Long.parseLong(s); - } catch (IOException | NumberFormatException e) { /* ignored */ } + } catch (IOException | NumberFormatException e) { } // ignored return pagesize; } // Fill object with info read from proc file system - public static HugePageConfiguration readFromOS() { + public static HugePageConfiguration readFromOS() throws IOException { return new HugePageConfiguration(readSupportedHugePagesFromOS(), readDefaultHugePageSizeFromOS(), readTHPModeFromOS(), readTHPPageSizeFromOS()); } - private static long parseSIUnit(String num, String unit) { + public static long parseSIUnit(String num, String unit) { long n = Long.parseLong(num); return switch (unit) { case "K" -> n * 1024; @@ -180,7 +227,7 @@ // [0.001s][info][pagesize] Transparent hugepage (THP) support: // [0.001s][info][pagesize] THP mode: madvise // [0.001s][info][pagesize] THP pagesize: 2M - TreeSet hugepages = new TreeSet<>(); + TreeSet staticHugePageConfigs = new TreeSet<>(); long defaultHugepageSize = 0; THPMode thpMode = THPMode.never; long thpPageSize = 0; @@ -192,7 +239,9 @@ for (String s : lines) { Matcher mat = patternHugepageSize.matcher(s); if (mat.matches()) { - hugepages.add(parseSIUnit(mat.group(1), mat.group(2))); + StaticHugePageConfig config = new StaticHugePageConfig(); + config.pageSize = parseSIUnit(mat.group(1), mat.group(2)); + staticHugePageConfigs.add(config); continue; } if (defaultHugepageSize == 0) { @@ -215,7 +264,7 @@ } } - return new HugePageConfiguration(hugepages, defaultHugepageSize, thpMode, thpPageSize); + return new HugePageConfiguration(staticHugePageConfigs, defaultHugepageSize, thpMode, thpPageSize); } } diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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=Default + * @summary Test JVM large page setup (default options) + * @library /test/lib + * @requires os.family == "linux" + * @modules java.base/jdk.internal.misc + * java.management + * @run driver TestHugePageDecisionsAtVMStartup + */ + +/* + * @test id=LP_enabled + * @summary Test JVM large page setup (+LP) + * @library /test/lib + * @requires os.family == "linux" + * @modules java.base/jdk.internal.misc + * java.management + * @run driver TestHugePageDecisionsAtVMStartup -XX:+UseLargePages + */ + +/* + * @test id=THP_enabled + * @summary Test JVM large page setup (+THP) + * @library /test/lib + * @requires os.family == "linux" + * @modules java.base/jdk.internal.misc + * java.management + * @run driver TestHugePageDecisionsAtVMStartup -XX:+UseTransparentHugePages + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +public class TestHugePageDecisionsAtVMStartup { + + // End user warnings, printing with Xlog:pagesize at warning level, should be unconditional + static final String warningNoTHP = "[warning][pagesize] UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system."; + static final String warningNoLP = "[warning][pagesize] UseLargePages disabled, no large pages configured and available on the system."; + + static final String buildSizeString(long l) { + String units[] = { "K", "M", "G" }; + long factor = 1024 * 1024 * 1024; + for (int i = 2; i >= 0; i--) { + if (l >= factor) { + return Long.toString(l / factor) + units[i]; + } + factor /= 1024; + } + return Long.toString(l) + "B"; + } + + static void testOutput(boolean useLP, boolean useTHP, OutputAnalyzer out, HugePageConfiguration configuration) { + + // Note: If something goes wrong, the JVM warns but continues, so we should never see an exit value != 0 + out.shouldHaveExitValue(0); + + // Static hugepages: + // Let X = the default hugepage size of the system (the one in /proc/meminfo). + // The JVM will cycle through page sizes, starting at X, down to the smallest hugepage size. + // + // Example 1: a system with 1GB and 2MB pages, the default hugepage size is 1GB (can only be done + // via kernel parameter). the JVM should first attempt to use 1GB pages, failing that should try 2MB, failing + // that give up and disable -UseLargePages. + // + // Example 1: same system, but the default hugepage size is 2MB. The JVM should not attempt to use 1GB pages. + // + // This picture gets more complex with -XX:LargePageSizeInBytes, which overrides the default + // large page size; but we ignore this for now (feel free to extend the test to cover LBSiB too). + + boolean haveUsableStaticHugePages = false; + if (configuration.supportsStaticHugePages()) { + long defaultLargePageSize = configuration.getStaticDefaultHugePageSize(); + Set configs = configuration.getStaticHugePageConfigurations(); + for (HugePageConfiguration.StaticHugePageConfig config: configs) { + if (config.pageSize <= defaultLargePageSize) { + if (config.nr_hugepages > 0 || config.nr_overcommit_hugepages > 0) { + haveUsableStaticHugePages = true; break; + } + } + } + } + + if (useTHP && !useLP) { + useLP = true; // its implicit + } + + if (!useLP) { + out.shouldContain("[info][pagesize] Large page support disabled"); + } else if (useLP && !useTHP && + (!configuration.supportsStaticHugePages() || !haveUsableStaticHugePages)) { + out.shouldContain(warningNoLP); + } else if (useLP && useTHP && !configuration.supportsTHP()) { + out.shouldContain(warningNoTHP); + } else if (useLP && !useTHP && + configuration.supportsStaticHugePages() && haveUsableStaticHugePages) { + out.shouldContain("[info][pagesize] Using the default large page size: " + buildSizeString(configuration.getStaticDefaultHugePageSize())); + out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=0"); + out.shouldContain("[info][pagesize] Large page support enabled"); + } else if (useLP && useTHP && configuration.supportsTHP()) { + String thpPageSizeString = buildSizeString(configuration.getThpPageSize()); + // We expect to see exactly two "Usable page sizes" : the system page size and the THP page size. The system + // page size differs, but its always in KB). + out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=1"); + out.shouldMatch(".*\\[info]\\[pagesize] Large page support enabled. Usable page sizes: \\d+[kK], " + thpPageSizeString + ". Default large page size: " + thpPageSizeString + ".*"); + } + } + + public static void main(String[] extraOptions) throws Exception { + List allOptions = new ArrayList(); + if (extraOptions != null) { + allOptions.addAll(Arrays.asList(extraOptions)); + } + allOptions.add("-Xmx128m"); + allOptions.add("-Xlog:pagesize"); + allOptions.add("-version"); + + boolean useLP = allOptions.contains("-XX:+UseLargePages"); + boolean useTHP = allOptions.contains("-XX:+UseTransparentHugePages"); + System.out.println("useLP: " + useLP + " useTHP: " + useTHP); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(allOptions.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.reportDiagnosticSummary(); + HugePageConfiguration configuration = HugePageConfiguration.readFromOS(); + System.out.println("configuration read from OS:" + configuration); + + testOutput(useLP, useTHP, output, configuration); + } +} diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/reflect/ReflectOutOfMemoryError.java openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/reflect/ReflectOutOfMemoryError.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/runtime/reflect/ReflectOutOfMemoryError.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/runtime/reflect/ReflectOutOfMemoryError.java 2024-01-16 16:19:00.000000000 +0000 @@ -25,7 +25,7 @@ * @test * @bug 8297977 * @summary Test that throwing OOM from reflected method gets InvocationTargetException - * @run main/othervm/timeout=150 ReflectOutOfMemoryError + * @run main/othervm -Xmx128m ReflectOutOfMemoryError */ import java.lang.reflect.*; diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/HeapDump/FieldsInInstanceTest.java openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/HeapDump/FieldsInInstanceTest.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/HeapDump/FieldsInInstanceTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/HeapDump/FieldsInInstanceTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,190 @@ +/* + * 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.File; +import java.lang.ref.Reference; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import jdk.test.lib.Asserts; +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.hprof.model.JavaClass; +import jdk.test.lib.hprof.model.JavaHeapObject; +import jdk.test.lib.hprof.model.JavaObject; +import jdk.test.lib.hprof.model.JavaThing; +import jdk.test.lib.hprof.model.Snapshot; +import jdk.test.lib.hprof.parser.Reader; + +/* + * @test + * @bug 8317692 + * @summary Verifies heap dump contains all fields of an instance + * @library /test/lib + * @run driver FieldsInInstanceTest + */ +class FieldsInInstanceTarg extends LingeredApp { + + public static void main(String[] args) { + B b = new B(); + NoFields2 nf = new NoFields2(); + NoParentFields npf = new NoParentFields(); + OnlyParentFields opf = new OnlyParentFields(); + DirectParentNoFields dpnf = new DirectParentNoFields(); + LingeredApp.main(args); + Reference.reachabilityFence(b); + Reference.reachabilityFence(nf); + Reference.reachabilityFence(npf); + Reference.reachabilityFence(opf); + Reference.reachabilityFence(dpnf); + } + + interface I { + int i = -10; + } + static abstract class A implements I { + static boolean b; + int a = 3; + String s = "Field"; + } + static class B extends A { + static String f = null; + int a = 7; + double s = 0.5d; + } + + // no fields: + interface I1 { + } + static class NoFields1 { + } + static class NoFields2 extends NoFields1 implements I1 { + } + + // no parent fields + static class NoParentFields extends NoFields1 implements I1 { + int i1 = 1; + int i2 = 2; + } + + // only parent fields + static class Parent1 { + int i3 = 3; + } + static class OnlyParentFields extends Parent1 { + } + + // in between parent with no fields + static class DirectParentNoFields extends OnlyParentFields { + int i = 17; + } +} + +public class FieldsInInstanceTest { + + public static void main(String[] args) throws Exception { + File dumpFile = new File("Myheapdump.hprof"); + createDump(dumpFile, args); + verifyDump(dumpFile); + } + + private static void createDump(File dumpFile, String[] extraOptions) throws Exception { + LingeredApp theApp = null; + try { + theApp = new FieldsInInstanceTarg(); + + List extraVMArgs = new ArrayList<>(); + extraVMArgs.addAll(Arrays.asList(extraOptions)); + LingeredApp.startApp(theApp, extraVMArgs.toArray(new String[0])); + + //jcmd GC.heap_dump + JDKToolLauncher launcher = JDKToolLauncher + .createUsingTestJDK("jcmd") + .addToolArg(Long.toString(theApp.getPid())) + .addToolArg("GC.heap_dump") + .addToolArg(dumpFile.getAbsolutePath()); + Process p = ProcessTools.startProcess("jcmd", new ProcessBuilder(launcher.getCommand())); + // If something goes wrong with heap dumping most likely we'll get crash of the target VM. + while (!p.waitFor(5, TimeUnit.SECONDS)) { + if (!theApp.getProcess().isAlive()) { + log("ERROR: target VM died, killing jcmd..."); + p.destroyForcibly(); + throw new Exception("Target VM died"); + } + } + + if (p.exitValue() != 0) { + throw new Exception("Jcmd exited with code " + p.exitValue()); + } + } finally { + LingeredApp.stopApp(theApp); + } + } + + private static void verifyDump(File dumpFile) throws Exception { + Asserts.assertTrue(dumpFile.exists(), "Heap dump file not found."); + + log("Reading " + dumpFile + "..."); + try (Snapshot snapshot = Reader.readFile(dumpFile.getPath(), true, 0)) { + log("Resolving snapshot..."); + snapshot.resolve(true); + log("Snapshot resolved."); + + List bFields = getFields(snapshot, FieldsInInstanceTarg.B.class); + // B has 2 instance fields, A has 2 instance fields + Asserts.assertEquals(bFields.size(), 4); + // JavaObject reverses the order of fields, so fields of B are at the end. + // Order is only specified for supertypes, so we check if values are *anywhere* in their range + // by using the toString output. + String asString = bFields.subList(2, 4).toString(); + Asserts.assertTrue(asString.contains("0.5"), "value for field B.s not found"); + Asserts.assertTrue(asString.contains("7"), "value for field B.a not found"); + asString = bFields.subList(0, 2).toString(); + Asserts.assertTrue(asString.contains("3"), "value for field A.a not found"); + Asserts.assertTrue(asString.contains("Field"), "value for field A.s not found"); + + Asserts.assertEquals(getFields(snapshot, FieldsInInstanceTarg.NoFields2.class).size(), 0); + + Asserts.assertEquals(getFields(snapshot, FieldsInInstanceTarg.NoParentFields.class).size(), 2); + + Asserts.assertEquals(getFields(snapshot, FieldsInInstanceTarg.OnlyParentFields.class).size(), 1); + + Asserts.assertEquals(getFields(snapshot, FieldsInInstanceTarg.DirectParentNoFields.class).size(), 2); + } + } + + private static List getFields(Snapshot snapshot, Class clazz) { + JavaObject javaObject = (JavaObject) snapshot.findClass(clazz.getName()).getInstances(false).nextElement(); + List fields = Arrays.asList(javaObject.getFields()); + log("Fields for " + clazz + " (including superclasses): " + fields); + return fields; + } + + private static void log(Object s) { + System.out.println(s); + } + +} \ No newline at end of file diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,210 @@ +/* + * 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 8312174 + * @summary missing JVMTI events from vthreads parked during JVMTI attach + * @requires vm.continuations + * @requires vm.jvmti + * @requires vm.compMode != "Xcomp" + * @run main/othervm/native + * -Djdk.virtualThreadScheduler.parallelism=9 + * -Djdk.attach.allowAttachSelf=true -XX:+EnableDynamicAgentLoading VThreadEventTest attach + */ + +import com.sun.tools.attach.VirtualMachine; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.locks.LockSupport; +import java.util.List; +import java.util.ArrayList; + +/* + * The test uses custom implementation of the CountDownLatch class. + * The reason is we want the state of tested thread to be predictable. + * With java.util.concurrent.CountDownLatch it is not clear what thread state is expected. + */ +class CountDownLatch { + private int count = 0; + + CountDownLatch(int count) { + this.count = count; + } + + public synchronized void countDown() { + count--; + notify(); + } + + public synchronized void await() throws InterruptedException { + while (count > 0) { + wait(1); + } + } +} + +public class VThreadEventTest { + static final int TCNT1 = 10; + static final int TCNT2 = 4; + static final int TCNT3 = 4; + static final int THREAD_CNT = TCNT1 + TCNT2 + TCNT3; + + private static void log(String msg) { System.out.println(msg); } + + private static native int threadEndCount(); + private static native int threadMountCount(); + private static native int threadUnmountCount(); + + private static volatile boolean attached; + private static boolean failed; + private static List test1Threads = new ArrayList(TCNT1); + + private static CountDownLatch ready0 = new CountDownLatch(THREAD_CNT); + private static CountDownLatch ready1 = new CountDownLatch(TCNT1); + private static CountDownLatch ready2 = new CountDownLatch(THREAD_CNT); + private static CountDownLatch mready = new CountDownLatch(1); + + private static void await(CountDownLatch dumpedLatch) { + try { + dumpedLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + // The test1 vthreads are kept unmounted until interrupted after agent attach. + static final Runnable test1 = () -> { + synchronized (test1Threads) { + test1Threads.add(Thread.currentThread()); + } + log("test1 vthread started"); + ready0.countDown(); + await(mready); + ready1.countDown(); // to guaranty state is not State.WAITING after await(mready) + try { + Thread.sleep(20000); // big timeout to keep unmounted until interrupted + } catch (InterruptedException ex) { + // it is expected, ignore + } + ready2.countDown(); + }; + + // The test2 vthreads are kept mounted until agent attach. + static final Runnable test2 = () -> { + log("test2 vthread started"); + ready0.countDown(); + await(mready); + while (!attached) { + // keep mounted + } + ready2.countDown(); + }; + + // The test3 vthreads are kept mounted until agent attach. + static final Runnable test3 = () -> { + log("test3 vthread started"); + ready0.countDown(); + await(mready); + while (!attached) { + // keep mounted + } + LockSupport.parkNanos(10_000_000L); // will cause extra mount and unmount + ready2.countDown(); + }; + + public static void main(String[] args) throws Exception { + if (Runtime.getRuntime().availableProcessors() < 8) { + log("WARNING: test expects at least 8 processors."); + } + try (ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) { + for (int i = 0; i < TCNT1; i++) { + executorService.execute(test1); + } + for (int i = 0; i < TCNT2; i++) { + executorService.execute(test2); + } + for (int i = 0; i < TCNT3; i++) { + executorService.execute(test3); + } + await(ready0); + mready.countDown(); + await(ready1); // to guaranty state is not State.WAITING after await(mready) in test1() + // wait for test1 threads to reach WAITING state in sleep() + for (Thread t : test1Threads) { + Thread.State state = t.getState(); + log("DBG: state: " + state); + while (state != Thread.State.WAITING) { + Thread.sleep(10); + state = t.getState(); + log("DBG: state: " + state); + } + } + + VirtualMachine vm = VirtualMachine.attach(String.valueOf(ProcessHandle.current().pid())); + vm.loadAgentLibrary("VThreadEventTest"); + Thread.sleep(200); // to allow the agent to get ready + + attached = true; + for (Thread t : test1Threads) { + t.interrupt(); + } + ready2.await(); + } + // wait until all VirtualThreadEnd events have been sent + for (int sleepNo = 1; threadEndCount() < THREAD_CNT; sleepNo++) { + Thread.sleep(100); + if (sleepNo % 100 == 0) { // 10 sec period of waiting + log("main: waited seconds: " + sleepNo/10); + } + } + int threadEndCnt = threadEndCount(); + int threadMountCnt = threadMountCount(); + int threadUnmountCnt = threadUnmountCount(); + int threadEndExp = THREAD_CNT; + int threadMountExp = THREAD_CNT - TCNT2; + int threadUnmountExp = THREAD_CNT + TCNT3; + + log("ThreadEnd cnt: " + threadEndCnt + " (expected: " + threadEndExp + ")"); + log("ThreadMount cnt: " + threadMountCnt + " (expected: " + threadMountExp + ")"); + log("ThreadUnmount cnt: " + threadUnmountCnt + " (expected: " + threadUnmountExp + ")"); + + if (threadEndCnt != threadEndExp) { + log("FAILED: unexpected count of ThreadEnd events"); + failed = true; + } + if (threadMountCnt != threadMountExp) { + log("FAILED: unexpected count of ThreadMount events"); + failed = true; + } + if (threadUnmountCnt != threadUnmountExp) { + log("FAILED: unexpected count of ThreadUnmount events"); + failed = true; + } + if (failed) { + throw new RuntimeException("FAILED: event count is wrong"); + } + } + +} + diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/libVThreadEventTest.cpp openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/libVThreadEventTest.cpp --- openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/libVThreadEventTest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/libVThreadEventTest.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include +#include "jvmti_common.h" + +extern "C" { + +static jvmtiEnv *jvmti = nullptr; +static std::atomic thread_end_cnt(0); +static std::atomic thread_unmount_cnt(0); +static std::atomic thread_mount_cnt(0); + +void JNICALL VirtualThreadEnd(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread) { + thread_end_cnt++; +} + +void JNICALL VirtualThreadMount(jvmtiEnv* jvmti, ...) { + thread_mount_cnt++; +} + +void JNICALL VirtualThreadUnmount(jvmtiEnv* jvmti, ...) { + thread_unmount_cnt++; +} + +JNIEXPORT jint JNICALL +Java_VThreadEventTest_threadEndCount(JNIEnv* jni, jclass clazz) { + return thread_end_cnt; +} + +JNIEXPORT jint JNICALL +Java_VThreadEventTest_threadMountCount(JNIEnv* jni, jclass clazz) { + return thread_mount_cnt; +} + +JNIEXPORT jint JNICALL +Java_VThreadEventTest_threadUnmountCount(JNIEnv* jni, jclass clazz) { + return thread_unmount_cnt; +} + +JNIEXPORT jint JNICALL +Agent_OnAttach(JavaVM *vm, char *options, void *reserved) { + jvmtiEventCallbacks callbacks; + jvmtiCapabilities caps; + jvmtiError err; + + LOG("Agent_OnAttach started\n"); + if (vm->GetEnv(reinterpret_cast(&jvmti), JVMTI_VERSION) != JNI_OK || !jvmti) { + LOG("Could not initialize JVMTI env\n"); + return JNI_ERR; + } + memset(&caps, 0, sizeof(caps)); + caps.can_support_virtual_threads = 1; + check_jvmti_error(jvmti->AddCapabilities(&caps), "AddCapabilities"); + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.VirtualThreadEnd = &VirtualThreadEnd; + + err = jvmti->SetEventCallbacks(&callbacks, (jint)sizeof(callbacks)); + check_jvmti_error(err, "SetEventCallbacks"); + + err = set_ext_event_callback(jvmti, "VirtualThreadMount", VirtualThreadMount); + check_jvmti_error(err, "SetExtEventCallback for VirtualThreadMount"); + + err = set_ext_event_callback(jvmti, "VirtualThreadUnmount", VirtualThreadUnmount); + check_jvmti_error(err, "SetExtEventCallback for VirtualThreadUnmount"); + + err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VIRTUAL_THREAD_END, nullptr); + check_jvmti_error(err, "SetEventNotificationMode for VirtualThreadEnd"); + + err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, EXT_EVENT_VIRTUAL_THREAD_MOUNT, nullptr); + check_jvmti_error(err, "SetEventNotificationMode for VirtualThreadMount"); + + err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, EXT_EVENT_VIRTUAL_THREAD_UNMOUNT, nullptr); + check_jvmti_error(err, "SetEventNotificationMode for VirtualThreadUnmount"); + + LOG("vthread events enabled\n"); + return JVMTI_ERROR_NONE; +} + +} // extern "C" + diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java --- openjdk-21-21.0.1+12/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java 2024-01-16 16:19:00.000000000 +0000 @@ -73,6 +73,9 @@ static void test(String type) throws Throwable { ProcessBuilder pb = ProcessTools.createTestJvm("-XX:+CreateCoredumpOnCrash", "-Xmx512m", "-XX:MaxMetaspaceSize=64m", "-XX:+CrashOnOutOfMemoryError", + // The test loads lots of small classes to exhaust Metaspace, skip method + // dependency verification to improve performance in debug builds. + Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "--show-version", CoreUtils.getAlwaysPretouchArg(true), TestJmapCore.class.getName(), type); diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_cl/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_cl/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_cl/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_cl/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_class/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_class/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_class/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_class/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_obj/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_obj/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_obj/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_obj/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load001/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load001/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load001/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load001/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load002/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load002/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load002/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load002/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load003/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load003/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load003/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load003/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load004/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load004/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load004/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load004/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load005/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load005/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load005/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load005/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load006/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load006/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load006/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load006/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load008/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load008/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load008/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load008/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load009/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load009/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load009/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load009/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load010/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load010/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load010/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load010/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload001/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload001/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload001/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload001/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload002/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload002/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload002/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload002/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload003/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload003/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload003/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload003/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload004/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload004/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload004/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload004/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload005/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload005/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload005/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload005/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload006/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload006/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload006/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload006/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload007/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload007/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload007/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload007/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload008/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload008/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload008/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload008/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload009/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload009/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload009/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload009/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload010/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload010/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload010/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload010/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload011/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload011/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload011/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload011/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload012/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload012/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload012/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload012/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem001/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem001/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem001/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem001/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem002/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem002/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem002/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem002/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem003/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem003/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem003/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem003/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem004/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem004/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem004/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem004/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem005/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem005/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem005/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem005/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem006/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem006/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem006/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem006/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem007/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem007/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem007/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem007/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem008/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem008/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem008/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem008/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem009/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem009/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem009/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem009/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem010/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem010/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem010/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem010/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem011/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem011/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem011/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem011/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem012/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem012/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem012/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem012/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem013/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem013/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem013/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem013/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem014/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem014/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem014/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem014/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem015/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem015/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem015/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem015/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem016/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem016/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem016/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem016/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem017/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem017/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem017/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem017/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem018/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem018/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem018/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem018/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem019/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem019/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem019/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem019/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem020/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem020/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem020/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem020/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem021/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem021/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem021/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem021/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem022/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem022/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem022/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem022/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem023/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem023/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem023/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem023/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem024/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem024/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem024/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem024/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem025/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem025/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem025/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem025/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem026/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem026/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem026/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem026/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem027/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem027/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem027/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem027/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem028/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem028/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem028/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem028/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem029/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem029/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem029/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem029/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem030/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem030/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem030/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem030/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem031/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem031/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem031/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem031/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem032/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem032/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem032/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem032/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem033/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem033/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem033/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem033/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem034/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem034/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem034/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem034/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem035/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem035/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem035/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem035/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem036/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem036/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem036/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem036/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon001/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon001/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon001/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon001/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon002/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon002/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon002/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon002/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon003/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon003/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon003/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon003/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace010/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace010/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace010/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace010/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace011/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace011/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace011/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace011/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace012/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace012/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace012/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace012/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace013/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace013/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace013/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace013/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace014/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace014/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace014/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace014/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace015/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace015/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace015/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace015/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace016/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace016/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace016/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace016/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace017/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace017/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace017/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace017/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace018/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace018/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace018/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace018/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/share/native/native_thread.cpp openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/share/native/native_thread.cpp --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/share/native/native_thread.cpp 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/share/native/native_thread.cpp 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2003, 2018, 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 @@ -128,11 +128,16 @@ return NULL; } #else // !windows & !sun - int result = pthread_create(&(thread->id),NULL,procedure,thread); + pthread_attr_t attr; + pthread_attr_init(&attr); + size_t stack_size = 0x100000; + pthread_attr_setstacksize(&attr, stack_size); + int result = pthread_create(&(thread->id), &attr, procedure, thread); if (result != 0) { perror("failed to create a native thread"); return NULL; } + pthread_attr_destroy(&attr); #endif // !windows & !sun }; return thread; diff -Nru openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/TEST.properties openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/TEST.properties --- openjdk-21-21.0.1+12/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/TEST.properties 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/TEST.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# Copyright (c) 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. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -exclusiveAccess.dirs=. diff -Nru openjdk-21-21.0.1+12/test/jaxp/TEST.ROOT openjdk-21-21.0.2+13/test/jaxp/TEST.ROOT --- openjdk-21-21.0.1+12/test/jaxp/TEST.ROOT 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jaxp/TEST.ROOT 2024-01-16 16:19:00.000000000 +0000 @@ -23,7 +23,7 @@ groups=TEST.groups # Minimum jtreg version -requiredVersion=7.2+1 +requiredVersion=7.3.1+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them diff -Nru openjdk-21-21.0.1+12/test/jdk/ProblemList.txt openjdk-21-21.0.2+13/test/jdk/ProblemList.txt --- openjdk-21-21.0.1+12/test/jdk/ProblemList.txt 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/ProblemList.txt 2024-01-16 16:19:00.000000000 +0000 @@ -375,7 +375,7 @@ java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java 8177326 macosx-all java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021 macosx-all java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java 8051455 macosx-all -java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java 7124407 macosx-all +java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java 7124407,8302787 macosx-all,windows-all java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java 8157170 macosx-all java/awt/Modal/ToFront/DialogToFrontModeless1Test.java 8213530 linux-all java/awt/Modal/ToFront/DialogToFrontNonModalTest.java 8221899 linux-all @@ -410,6 +410,7 @@ java/awt/Modal/ToBack/ToBackNonModal4Test.java 8196441 macosx-all,linux-all java/awt/Modal/ToBack/ToBackNonModal5Test.java 8196441 macosx-all javax/print/PrintSEUmlauts/PrintSEUmlauts.java 8135174 generic-all +java/awt/font/Rotate/RotatedTextTest.java 8219641 linux-all java/awt/font/TextLayout/LigatureCaretTest.java 8266312 generic-all java/awt/image/VolatileImage/CustomCompositeTest.java 8199002 windows-all,linux-all java/awt/image/VolatileImage/GradientPaints.java 8199003 linux-all @@ -450,7 +451,10 @@ java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all +java/awt/Graphics2D/DrawString/RotTransText.java 8316878 linux-all java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest.java 8257529 windows-x64 +java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeForModalDialogTest/ConsumeForModalDialogTest.java 8302787 windows-all +java/awt/KeyboardFocusmanager/TypeAhead/MenuItemActivatedTest/MenuItemActivatedTest.java 8302787 windows-all java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 @@ -477,7 +481,7 @@ java/lang/ProcessHandle/InfoTest.java 8211847 aix-ppc64 java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java 8151492 generic-all java/lang/invoke/LFCaching/LFGarbageCollectedTest.java 8078602 generic-all -java/lang/invoke/lambda/LambdaFileEncodingSerialization.java 8249079 linux-x64 +java/lang/invoke/lambda/LambdaFileEncodingSerialization.java 8249079 linux-all java/lang/invoke/RicochetTest.java 8251969 generic-all ############################################################################ @@ -528,15 +532,24 @@ # jdk_net +java/net/DatagramSocket/DatagramSocketExample.java 8308807 aix-ppc64 +java/net/DatagramSocket/DatagramSocketMulticasting.java 8308807 aix-ppc64 + +java/net/MulticastSocket/B6427403.java 8308807 aix-ppc64 +java/net/MulticastSocket/IPMulticastIF.java 8308807 aix-ppc64 +java/net/MulticastSocket/JoinLeave.java 8308807 aix-ppc64 +java/net/MulticastSocket/MulticastAddresses.java 8308807 aix-ppc64 java/net/MulticastSocket/NoLoopbackPackets.java 7122846,8308807 macosx-all,aix-ppc64 +java/net/MulticastSocket/NoSetNetworkInterface.java 8308807 aix-ppc64 +java/net/MulticastSocket/Promiscuous.java 8308807 aix-ppc64 +java/net/MulticastSocket/SetGetNetworkInterfaceTest.java 8308807 aix-ppc64 java/net/MulticastSocket/SetLoopbackMode.java 7122846,8308807 macosx-all,aix-ppc64 - +java/net/MulticastSocket/SetOutgoingIf.java 8308807 aix-ppc64 java/net/MulticastSocket/Test.java 7145658,8308807 macosx-all,aix-ppc64 java/net/ServerSocket/AcceptInheritHandle.java 8211854 aix-ppc64 -java/net/MulticastSocket/B6427403.java 8308807 aix-ppc64 -java/net/MulticastSocket/SetOutgoingIf.java 8308807 aix-ppc64 +java/net/Socket/asyncClose/Race.java 8317801 aix-ppc64 ############################################################################ @@ -544,8 +557,11 @@ java/nio/channels/AsynchronousSocketChannel/StressLoopback.java 8211851 aix-ppc64 -java/nio/channels/DatagramChannel/ManySourcesAndTargets.java 8264385 macosx-aarch64 +java/nio/channels/Channels/SocketChannelStreams.java 8317838 aix-ppc64 +java/nio/channels/DatagramChannel/AdaptorMulticasting.java 8308807 aix-ppc64 +java/nio/channels/DatagramChannel/AfterDisconnect.java 8308807 aix-ppc64 +java/nio/channels/DatagramChannel/ManySourcesAndTargets.java 8264385 macosx-aarch64 java/nio/channels/DatagramChannel/Unref.java 8233437 generic-all jdk/nio/zipfs/TestLocOffsetFromZip64EF.java 8301183 linux-all @@ -563,6 +579,7 @@ java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java 7191877 generic-all java/rmi/registry/readTest/CodebaseTest.java 8173324 windows-all +java/rmi/registry/multipleRegistries/MultipleRegistries.java 8268182 macosx-all java/rmi/Naming/DefaultRegistryPort.java 8005619 windows-all java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java 8005619 windows-all @@ -581,8 +598,6 @@ # jdk_security -sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8161536 generic-all - sun/security/smartcardio/TestChannel.java 8039280 generic-all sun/security/smartcardio/TestConnect.java 8039280 generic-all sun/security/smartcardio/TestConnectAgain.java 8039280 generic-all @@ -698,8 +713,6 @@ com/sun/jdi/InvokeHangTest.java 8218463 linux-all -com/sun/jdi/AfterThreadDeathTest.java 8232839 linux-all - ############################################################################ # jdk_time @@ -712,7 +725,6 @@ sun/util/locale/provider/CalendarDataRegression.java 8268379 macosx-x64 java/util/concurrent/forkjoin/AsyncShutdownNow.java 8286352 linux-all,windows-x64 java/util/concurrent/ExecutorService/CloseTest.java 8288899 macosx-aarch64 -java/util/concurrent/SynchronousQueue/Fairness.java 8300663 generic-x64 ############################################################################ @@ -722,14 +734,12 @@ # svc_tools -sun/tools/jstatd/TestJstatdDefaults.java 8081569,8226420 windows-all sun/tools/jstatd/TestJstatdRmiPort.java 8226420,8251259,8293577 generic-all -sun/tools/jstatd/TestJstatdServer.java 8081569,8226420 windows-all -sun/tools/jstat/jstatLineCounts1.sh 8268211 linux-aarch64 -sun/tools/jstat/jstatLineCounts2.sh 8268211 linux-aarch64 -sun/tools/jstat/jstatLineCounts3.sh 8268211 linux-aarch64 -sun/tools/jstat/jstatLineCounts4.sh 8268211 linux-aarch64 +sun/tools/jstat/jstatLineCounts1.sh 8248691,8268211 linux-ppc64le,aix-ppc64,linux-aarch64 +sun/tools/jstat/jstatLineCounts2.sh 8248691,8268211 linux-ppc64le,aix-ppc64,linux-aarch64 +sun/tools/jstat/jstatLineCounts3.sh 8248691,8268211 linux-ppc64le,aix-ppc64,linux-aarch64 +sun/tools/jstat/jstatLineCounts4.sh 8248691,8268211 linux-ppc64le,aix-ppc64,linux-aarch64 sun/tools/jhsdb/JStackStressTest.java 8276210 linux-aarch64 @@ -747,6 +757,7 @@ # jdk_jfr jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 generic-all +jdk/jfr/event/runtime/TestResidentSetSizeEvent.java 8309846 aix-ppc64 jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64 jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64 jdk/jfr/jvm/TestWaste.java 8282427 generic-all diff -Nru openjdk-21-21.0.1+12/test/jdk/TEST.ROOT openjdk-21-21.0.2+13/test/jdk/TEST.ROOT --- openjdk-21-21.0.1+12/test/jdk/TEST.ROOT 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/TEST.ROOT 2024-01-16 16:19:00.000000000 +0000 @@ -31,7 +31,7 @@ java/rmi/Naming java/util/prefs sun/management/jmxremote \ sun/tools/jstatd sun/security/mscapi java/util/Arrays/largeMemory \ java/util/BitSet/stream javax/rmi java/net/httpclient/websocket \ -com/sun/net/httpserver/simpleserver +com/sun/net/httpserver/simpleserver sun/tools/jhsdb # Group definitions groups=TEST.groups @@ -79,7 +79,7 @@ jdk.foreign.linker # Minimum jtreg version -requiredVersion=7.2+1 +requiredVersion=7.3.1+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them diff -Nru openjdk-21-21.0.1+12/test/jdk/TEST.groups openjdk-21-21.0.2+13/test/jdk/TEST.groups --- openjdk-21-21.0.1+12/test/jdk/TEST.groups 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/TEST.groups 2024-01-16 16:19:00.000000000 +0000 @@ -366,28 +366,8 @@ jdk/incubator/vector jdk_vector_sanity = \ - jdk/incubator/vector/AddTest.java \ - jdk/incubator/vector/ByteMaxVectorLoadStoreTests.java \ - jdk/incubator/vector/ByteMaxVectorTests.java \ - jdk/incubator/vector/CovarOverrideTest.java \ - jdk/incubator/vector/DoubleMaxVectorLoadStoreTests.java \ - jdk/incubator/vector/DoubleMaxVectorTests.java \ - jdk/incubator/vector/FloatMaxVectorLoadStoreTests.java \ - jdk/incubator/vector/FloatMaxVectorTests.java \ - jdk/incubator/vector/ImageTest.java \ - jdk/incubator/vector/IntMaxVectorLoadStoreTests.java \ - jdk/incubator/vector/IntMaxVectorTests.java \ - jdk/incubator/vector/LoadJsvmlTest.java \ - jdk/incubator/vector/LongMaxVectorLoadStoreTests.java \ - jdk/incubator/vector/LongMaxVectorTests.java \ - jdk/incubator/vector/MethodOverideTest.java \ - jdk/incubator/vector/MismatchTest.java \ jdk/incubator/vector/PreferredSpeciesTest.java \ - jdk/incubator/vector/ShortMaxVectorLoadStoreTests.java \ - jdk/incubator/vector/ShortMaxVectorTests.java \ jdk/incubator/vector/VectorHash.java \ - jdk/incubator/vector/VectorMaxConversionTests.java \ - jdk/incubator/vector/VectorReshapeTests.java \ jdk/incubator/vector/VectorRuns.java ############################# diff -Nru openjdk-21-21.0.1+12/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java openjdk-21-21.0.2+13/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java --- openjdk-21-21.0.1+12/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, Alphabet LLC. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8314045 + * @summary ArithmeticException in GaloisCounterMode + */ + +import java.nio.ByteBuffer; + +import javax.crypto.AEADBadTagException; +import javax.crypto.Cipher; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class GCMShortInput { + + public static void main(String args[]) throws Exception { + SecretKeySpec keySpec = + new SecretKeySpec( + new byte[] { + 88, 26, 43, -100, -24, -29, -70, 10, 34, -85, 52, 101, 45, -68, -105, + -123 + }, + "AES"); + GCMParameterSpec params = + new GCMParameterSpec(8 * 16, new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + cipher.init(Cipher.DECRYPT_MODE, keySpec, params); + try { + cipher.doFinal(ByteBuffer.allocate(0), ByteBuffer.allocate(0)); + throw new AssertionError("AEADBadTagException expected"); + } catch (AEADBadTagException e) { + // expected + } + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/AfterThreadDeathTest.java openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/AfterThreadDeathTest.java --- openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/AfterThreadDeathTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/AfterThreadDeathTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, 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 @@ -51,9 +51,9 @@ public class AfterThreadDeathTest extends TestScaffold { ReferenceType targetClass; ThreadReference mainThread; - StepRequest stepRequest = null; EventRequestManager erm; - boolean mainIsDead; + volatile boolean mainIsDead = false; + volatile boolean gotExpectedThreadStart = false; AfterThreadDeathTest (String args[]) { super(args); @@ -68,20 +68,23 @@ public void threadStarted(ThreadStartEvent event) { println("Got ThreadStartEvent: " + event); - if (stepRequest != null) { - erm.deleteEventRequest(stepRequest); - stepRequest = null; - println("Deleted stepRequest"); + // We don't want to attempt the StepRequest.enable() until we recieve + // the ThreadStartEvent for the "DestroyJavaVM" thread. See JDK-8232839. + if (!event.thread().name().equals("DestroyJavaVM")) { + return; } + gotExpectedThreadStart = true; - if (mainIsDead) { + if (!mainIsDead) { + failure("FAILED: Got expected ThreadStartEvent before \"main\" ThreadDeathEvent"); + } else { // Here is the odd thing about this test; whatever thread this event // is for, we do a step on the mainThread. If the mainThread is // already dead, we should get the exception. Note that we don't // come here for the start of the main thread. - stepRequest = erm.createStepRequest(mainThread, - StepRequest.STEP_LINE, - StepRequest.STEP_OVER); + StepRequest stepRequest = erm.createStepRequest(mainThread, + StepRequest.STEP_LINE, + StepRequest.STEP_OVER); stepRequest.addCountFilter(1); stepRequest.setSuspendPolicy (EventRequest.SUSPEND_ALL); try { @@ -146,6 +149,13 @@ */ listenUntilVMDisconnect(); + if (!gotExpectedThreadStart) { + failure("FAILED: never got expected ThreadStartEvent"); + } + if (!mainIsDead) { + failure("FAILED: never got ThreadDeathEvent for \"main\" thread"); + } + /* * deal with results of test * if anything has called failure("foo") testFailed will be true diff -Nru openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/EATests.java openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/EATests.java --- openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/EATests.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/EATests.java 2024-01-16 16:19:00.000000000 +0000 @@ -42,6 +42,7 @@ * -XX:+WhiteBoxAPI * -Xbatch * -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1 * @run driver EATests * -XX:+UnlockDiagnosticVMOptions * -Xms256m -Xmx256m @@ -50,6 +51,7 @@ * -XX:+WhiteBoxAPI * -Xbatch * -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1 * @run driver EATests * -XX:+UnlockDiagnosticVMOptions * -Xms256m -Xmx256m @@ -58,6 +60,7 @@ * -XX:+WhiteBoxAPI * -Xbatch * -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1 * @run driver EATests * -XX:+UnlockDiagnosticVMOptions * -Xms256m -Xmx256m @@ -66,6 +69,44 @@ * -XX:+WhiteBoxAPI * -Xbatch * -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1 + * + * @run driver EATests + * -XX:+UnlockDiagnosticVMOptions + * -Xms256m -Xmx256m + * -Xbootclasspath/a:. + * -XX:CompileCommand=dontinline,*::dontinline_* + * -XX:+WhiteBoxAPI + * -Xbatch + * -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2 + * @run driver EATests + * -XX:+UnlockDiagnosticVMOptions + * -Xms256m -Xmx256m + * -Xbootclasspath/a:. + * -XX:CompileCommand=dontinline,*::dontinline_* + * -XX:+WhiteBoxAPI + * -Xbatch + * -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2 + * @run driver EATests + * -XX:+UnlockDiagnosticVMOptions + * -Xms256m -Xmx256m + * -Xbootclasspath/a:. + * -XX:CompileCommand=dontinline,*::dontinline_* + * -XX:+WhiteBoxAPI + * -Xbatch + * -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2 + * @run driver EATests + * -XX:+UnlockDiagnosticVMOptions + * -Xms256m -Xmx256m + * -Xbootclasspath/a:. + * -XX:CompileCommand=dontinline,*::dontinline_* + * -XX:+WhiteBoxAPI + * -Xbatch + * -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks + * -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2 * * @comment Excercise -XX:+DeoptimizeObjectsALot. Mostly to prevent bit-rot because the option is meant to stress object deoptimization * with non-synthetic workloads. @@ -208,11 +249,13 @@ // Relocking test cases new EARelockingSimpleTarget() .run(); + new EARelockingSimpleWithAccessInOtherThreadTarget() .run(); new EARelockingRecursiveTarget() .run(); new EARelockingNestedInflatedTarget() .run(); new EARelockingNestedInflated_02Target() .run(); new EARelockingArgEscapeLWLockedInCalleeFrameTarget() .run(); new EARelockingArgEscapeLWLockedInCalleeFrame_2Target() .run(); + new EARelockingArgEscapeLWLockedInCalleeFrameNoRecursiveTarget() .run(); new EAGetOwnedMonitorsTarget() .run(); new EAEntryCountTarget() .run(); new EARelockingObjectCurrentlyWaitingOnTarget() .run(); @@ -325,11 +368,13 @@ // Relocking test cases new EARelockingSimple() .run(this); + new EARelockingSimpleWithAccessInOtherThread() .run(this); new EARelockingRecursive() .run(this); new EARelockingNestedInflated() .run(this); new EARelockingNestedInflated_02() .run(this); new EARelockingArgEscapeLWLockedInCalleeFrame() .run(this); new EARelockingArgEscapeLWLockedInCalleeFrame_2() .run(this); + new EARelockingArgEscapeLWLockedInCalleeFrameNoRecursive() .run(this); new EAGetOwnedMonitors() .run(this); new EAEntryCount() .run(this); new EARelockingObjectCurrentlyWaitingOn() .run(this); @@ -1703,6 +1748,62 @@ ///////////////////////////////////////////////////////////////////////////// +// The debugger reads and publishes an object with eliminated locking to an instance field. +// A 2nd thread in the debuggee finds it there and changes its state using a synchronized method. +// Without eager relocking the accesses are unsynchronized which can be observed. +class EARelockingSimpleWithAccessInOtherThread extends EATestCaseBaseDebugger { + + public void runTestCase() throws Exception { + BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V"); + printStack(bpe.thread()); + String l1ClassName = EARelockingSimpleWithAccessInOtherThreadTarget.SyncCounter.class.getName(); + ObjectReference ctr = getLocalRef(bpe.thread().frame(1), l1ClassName, "l1"); + setField(testCase, "sharedCounter", ctr); + terminateEndlessLoop(); + } +} + +class EARelockingSimpleWithAccessInOtherThreadTarget extends EATestCaseBaseTarget { + + public static class SyncCounter { + private int val; + public synchronized int inc() { return val++; } + } + + public volatile SyncCounter sharedCounter; + + @Override + public void setUp() { + super.setUp(); + doLoop = true; + Thread.ofPlatform().daemon().start(() -> { + while (doLoop) { + SyncCounter ctr = sharedCounter; + if (ctr != null) { + ctr.inc(); + } + } + }); + } + + public void dontinline_testMethod() { + SyncCounter l1 = new SyncCounter(); + synchronized (l1) { // Eliminated locking + l1.inc(); + dontinline_brkpt(); // Debugger publishes l1 to sharedCounter. + iResult = l1.inc(); // Changes by the 2nd thread will be observed if l1 + // was not relocked before passing it to the debugger. + } + } + + @Override + public int getExpectedIResult() { + return 1; + } +} + +///////////////////////////////////////////////////////////////////////////// + // Test recursive locking class EARelockingRecursiveTarget extends EATestCaseBaseTarget { @@ -1891,6 +1992,48 @@ } } iResult = l2.x + l2.y; + } + + @Override + public int getExpectedIResult() { + return 6; + } +} + +///////////////////////////////////////////////////////////////////////////// + +/** + * Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame_2Target}. It does + * not use recursive locking and exposed a bug in the lightweight-locking implementation. + */ +class EARelockingArgEscapeLWLockedInCalleeFrameNoRecursive extends EATestCaseBaseDebugger { + + public void runTestCase() throws Exception { + BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V"); + printStack(bpe.thread()); + @SuppressWarnings("unused") + ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1"); + } +} + +class EARelockingArgEscapeLWLockedInCalleeFrameNoRecursiveTarget extends EATestCaseBaseTarget { + + @Override + public void setUp() { + super.setUp(); + testMethodDepth = 2; + } + + public void dontinline_testMethod() { + XYVal l1 = new XYVal(1, 1); // NoEscape, scalar replaced + XYVal l2 = new XYVal(4, 2); // NoEscape, scalar replaced + XYVal l3 = new XYVal(5, 3); // ArgEscape + synchronized (l1) { // eliminated + synchronized (l2) { // eliminated + l3.dontinline_sync_method(this); // l3 escapes + } + } + iResult = l2.x + l2.y; } @Override diff -Nru openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/JdwpOnThrowTest.java openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/JdwpOnThrowTest.java --- openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/JdwpOnThrowTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/JdwpOnThrowTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 com.sun.jdi.Bootstrap; +import com.sun.jdi.VirtualMachine; +import com.sun.jdi.connect.AttachingConnector; +import com.sun.jdi.connect.Connector; +import com.sun.jdi.connect.IllegalConnectorArgumentsException; +import com.sun.jdi.event.EventIterator; +import com.sun.jdi.event.EventQueue; +import com.sun.jdi.event.EventSet; +import com.sun.jdi.event.Event; +import com.sun.jdi.event.ExceptionEvent; +import lib.jdb.Debuggee; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/* + * @test + * @bug 8317920 + * @summary Tests for JDWP agent to send valid exception event with onthrow option + * @library /test/lib + * + * @build ThrowCaughtException JdwpOnThrowTest + * @run main/othervm JdwpOnThrowTest + */ +public class JdwpOnThrowTest { + + private static long TIMEOUT = 10000; + + private static String ATTACH_CONNECTOR = "com.sun.jdi.SocketAttach"; + // cache socket attaching connector + private static AttachingConnector attachingConnector; + + public static void main(String[] args) throws Exception { + try (Debuggee debuggee = Debuggee.launcher("ThrowCaughtException") + .enableOnThrow("Ex").setSuspended(true).launch()) { + VirtualMachine vm = null; + try { + vm = attach("localhost", debuggee.getAddress()); + EventQueue queue = vm.eventQueue(); + log("Waiting for exception event"); + long start = System.currentTimeMillis(); + while (start + TIMEOUT > System.currentTimeMillis()) { + EventSet eventSet = queue.remove(TIMEOUT); + EventIterator eventIterator = eventSet.eventIterator(); + while(eventIterator.hasNext() && start + TIMEOUT > System.currentTimeMillis()) { + Event event = eventIterator.next(); + if (event instanceof ExceptionEvent ex) { + verifyExceptionEvent(ex); + log("Received exception event: " + event); + vm.dispose(); + return; + } + log("Received event: " + event); + } + } + throw new RuntimeException("ERROR: failed to receive exception event"); + } catch (IOException ex) { + throw new RuntimeException("ERROR: failed to attach", ex); + } + } + } + + private static void verifyExceptionEvent(ExceptionEvent ex) throws Exception { + if (ex.exception() == null) { + throw new RuntimeException("Exception is null"); + } + if (ex.exception().type() == null) { + throw new RuntimeException("Exception type is null"); + } + if (ex.exception().referenceType() == null) { + throw new RuntimeException("Exception reference type is null"); + } + if (ex.catchLocation() == null) { + throw new RuntimeException("Exception catch location is null"); + } + if (!ex.location().equals(ex.thread().frame(0).location())) { + throw new RuntimeException( + String.format("Throw location %s and location of first frame %s are not equal", + ex.location(), ex.thread().frame(0).location())); + } + if (!ex.exception().type().name().equals("Ex")) { + throw new RuntimeException("Exception has wrong type: " + ex.exception().type().name()); + } + } + + private static VirtualMachine attach(String address, String port) throws IOException { + if (attachingConnector == null) { + attachingConnector = (AttachingConnector)getConnector(ATTACH_CONNECTOR); + } + Map args = attachingConnector.defaultArguments(); + setConnectorArg(args, "hostname", address); + setConnectorArg(args, "port", port); + try { + return attachingConnector.attach(args); + } catch (IllegalConnectorArgumentsException e) { + // unexpected.. wrap in RuntimeException + throw new RuntimeException(e); + } + } + + private static Connector getConnector(String name) { + for (Connector connector : Bootstrap.virtualMachineManager().allConnectors()) { + if (connector.name().equalsIgnoreCase(name)) { + return connector; + } + } + throw new IllegalArgumentException("Connector " + name + " not found"); + } + + private static void setConnectorArg(Map args, String name, String value) { + Connector.Argument arg = args.get(name); + if (arg == null) { + throw new IllegalArgumentException("Argument " + name + " is not defined"); + } + arg.setValue(value); + } + + private static void log(Object o) { + System.out.println(String.valueOf(o)); + } + +} diff -Nru openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/ThrowCaughtException.java openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/ThrowCaughtException.java --- openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/ThrowCaughtException.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/ThrowCaughtException.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + public class ThrowCaughtException { + public static void main(String args[]) throws Exception { + try { + System.out.println("Start"); + throw new Ex(); + } catch (Exception e) { + System.out.println(e); + } + } +} + +class Ex extends RuntimeException { +} diff -Nru openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java --- openjdk-21-21.0.1+12/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,9 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -68,6 +71,8 @@ private String transport = "dt_socket"; private String address = null; private boolean suspended = true; + private String onthrow = ""; + private static final String LAUNCH_ECHO_STRING = "Listen Args:"; private Launcher(String mainClass) { this.mainClass = mainClass; @@ -100,35 +105,59 @@ return this; } + public Launcher enableOnThrow(String exceptionClassName) { + this.onthrow = exceptionClassName; + return this; + } + public ProcessBuilder prepare() { List debuggeeArgs = new LinkedList<>(); if (vmOptions != null) { debuggeeArgs.add(vmOptions); } + String onthrowArgs = onthrow.isEmpty() ? "" : ",onthrow=" + onthrow + ",launch=echo " + LAUNCH_ECHO_STRING; debuggeeArgs.add("-agentlib:jdwp=transport=" + transport + (address == null ? "" : ",address=" + address) - + ",server=y,suspend=" + (suspended ? "y" : "n")); + + ",server=y,suspend=" + (suspended ? "y" : "n") + + onthrowArgs); debuggeeArgs.addAll(options); debuggeeArgs.add(mainClass); return ProcessTools.createTestJvm(debuggeeArgs); } public Debuggee launch(String name) { - return new Debuggee(prepare(), name); + return new Debuggee(prepare(), name, + onthrow.isEmpty() ? + JDWP::parseListenAddress : + Launcher::parseLaunchEchoListenAddress + ); } public Debuggee launch() { return launch("debuggee"); } + + /** + * Parses debuggee output to get listening transport and address, printed by `launch=echo`. + * Returns null if the string specified does not contain required info. + */ + private static JDWP.ListenAddress parseLaunchEchoListenAddress(String debuggeeOutput) { + Pattern listenRegexp = Pattern.compile(LAUNCH_ECHO_STRING + " \\b(.+)\\b \\b(.+)\\b"); + Matcher m = listenRegexp.matcher(debuggeeOutput); + if (m.find()) { + return new JDWP.ListenAddress(m.group(1), m.group(2)); + } + return null; + } } - // starts the process, waits for "Listening for transport" output and detects transport/address - private Debuggee(ProcessBuilder pb, String name) { + // starts the process, waits until the provided addressDetector detects transport/address from the process output + private Debuggee(ProcessBuilder pb, String name, Function addressDetector) { JDWP.ListenAddress[] listenAddress = new JDWP.ListenAddress[1]; try { p = ProcessTools.startProcess(name, pb, s -> output.add(s), // output consumer - s -> { // warm-up predicate - listenAddress[0] = JDWP.parseListenAddress(s); + s -> { + listenAddress[0] = addressDetector.apply(s); return listenAddress[0] != null; }, 30, TimeUnit.SECONDS); @@ -167,10 +196,16 @@ } String getTransport() { + if (transport == null) { + throw new IllegalStateException("transport is not available"); + } return transport; } public String getAddress() { + if (address == null) { + throw new IllegalStateException("address is not available"); + } return address; } @@ -180,5 +215,4 @@ p.destroy(); } } - } diff -Nru openjdk-21-21.0.1+12/test/jdk/com/sun/tools/attach/warnings/DynamicLoadWarningTest.java openjdk-21-21.0.2+13/test/jdk/com/sun/tools/attach/warnings/DynamicLoadWarningTest.java --- openjdk-21-21.0.1+12/test/jdk/com/sun/tools/attach/warnings/DynamicLoadWarningTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/com/sun/tools/attach/warnings/DynamicLoadWarningTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -124,18 +124,15 @@ .whenRunning(loadJvmtiAgent1) .stderrShouldNotContain(JVMTI_AGENT_WARNING); - // test behavior on platforms that can detect if an agent library was previously loaded - if (!Platform.isAix()) { - // start loadJvmtiAgent1 via the command line, then dynamically load loadJvmtiAgent1 - test().withOpts("-agentpath:" + jvmtiAgentPath1) - .whenRunning(loadJvmtiAgent1) - .stderrShouldNotContain(JVMTI_AGENT_WARNING); + // start loadJvmtiAgent1 via the command line, then dynamically load loadJvmtiAgent1 + test().withOpts("-agentpath:" + jvmtiAgentPath1) + .whenRunning(loadJvmtiAgent1) + .stderrShouldNotContain(JVMTI_AGENT_WARNING); - // dynamically load loadJvmtiAgent1 twice, should be one warning - test().whenRunning(loadJvmtiAgent1) - .whenRunning(loadJvmtiAgent1) - .stderrShouldContain(JVMTI_AGENT_WARNING, 1); - } + // dynamically load loadJvmtiAgent1 twice, should be one warning + test().whenRunning(loadJvmtiAgent1) + .whenRunning(loadJvmtiAgent1) + .stderrShouldContain(JVMTI_AGENT_WARNING, 1); } /** diff -Nru openjdk-21-21.0.1+12/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java openjdk-21-21.0.2+13/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java --- openjdk-21-21.0.1+12/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -26,6 +26,7 @@ import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.font.FontRenderContext; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; @@ -61,15 +62,19 @@ new Color(0x7F000000, true) }; + /** Locale for getting font names. */ + private static final Locale ENGLISH_LOCALE = Locale.ENGLISH; + private static final AffineTransform STRETCH_TRANSFORM = AffineTransform.getScaleInstance(2.0, 1.0); public static void main(String[] args) { List errors = Arrays.stream(getLocalGraphicsEnvironment() - .getAvailableFontFamilyNames(Locale.ENGLISH)) + .getAvailableFontFamilyNames(ENGLISH_LOCALE)) .map(family -> new Font(family, Font.PLAIN, FONT_SIZE)) .filter(font -> font.canDisplay(TEXT.codePointAt(0))) + .filter(font -> !isBrokenFont(font)) .map(font -> font.deriveFont(STRETCH_TRANSFORM)) .flatMap(StretchedFontTest::testFont) .filter(Objects::nonNull) @@ -83,6 +88,26 @@ } /** + * Checks whether the font renders the glyph in {@code TEXT} and + * returns {@code true} if the glyph isn't rendered. + * + * @param font the font to test + * @return {@code true} if the visual bounds of {@code TEXT} are empty, and + * {@code false} otherwise + */ + private static boolean isBrokenFont(final Font font) { + final boolean empty = + font.createGlyphVector(new FontRenderContext(null, false, false), + TEXT) + .getVisualBounds() + .isEmpty(); + if (empty) { + System.err.println("Broken font: " + font.getFontName(ENGLISH_LOCALE)); + } + return empty; + } + + /** * Tests the font with a set of text antialiasing hints. * * @param font the font to test @@ -145,7 +170,7 @@ if (verifyImage(image)) { return null; } - String fontName = font.getFontName(Locale.ENGLISH); + String fontName = font.getFontName(ENGLISH_LOCALE); String hintValue = getHintString(hint); String hexColor = String.format("0x%08x", foreground.getRGB()); saveImage(image, fontName + "-" + hintValue + "-" + hexColor); diff -Nru openjdk-21-21.0.1+12/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java openjdk-21-21.0.2+13/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java --- openjdk-21-21.0.1+12/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -21,34 +21,131 @@ * questions. */ +import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Image; import java.awt.Insets; +import java.awt.Point; import java.awt.Rectangle; +import java.awt.Robot; import java.awt.Toolkit; import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.imageio.ImageIO; import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JDialog; +import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.Timer; +import javax.swing.text.JTextComponent; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; - +import static java.util.Collections.unmodifiableList; import static javax.swing.SwingUtilities.invokeAndWait; import static javax.swing.SwingUtilities.isEventDispatchThread; +/** + * Provides a framework for manual tests to display test instructions and + * Pass/Fail buttons. + *

+ * Instructions for the user can be either plain text or HTML as supported + * by Swing. If the instructions start with {@code }, the + * instructions are displayed as HTML. + *

+ * A simple test would look like this: + *

{@code
+ * public class SampleManualTest {
+ *     private static final String INSTRUCTIONS =
+ *             "Click Pass, or click Fail if the test failed.";
+ *
+ *     public static void main(String[] args) throws Exception {
+ *         PassFailJFrame.builder()
+ *                       .instructions(INSTRUCTIONS)
+ *                       .testUI(() -> createTestUI())
+ *                       .build()
+ *                       .awaitAndCheck();
+ *     }
+ *
+ *     private static List createTestUI() {
+ *         JFrame testUI = new JFrame("Test UI");
+ *         testUI.setSize(250, 150);
+ *         return List.of(testUI);
+ *     }
+ * }
+ * }
+ *

+ * The above example uses the {@link Builder Builder} to set the parameters of + * the instruction frame. It is the recommended way. + *

+ * The framework will create instruction UI, it will call + * the provided {@code createTestUI} on the Event Dispatch Thread (EDT), + * and it will automatically position the test UI and make it visible. + *

+ * Alternatively, use one of the {@code PassFailJFrame} constructors to + * create an object, then create secondary test UI, register it + * with {@code PassFailJFrame}, position it and make it visible. + * The following sample demonstrates it: + *

{@code
+ * public class SampleOldManualTest {
+ *     private static final String INSTRUCTIONS =
+ *             "Click Pass, or click Fail if the test failed.";
+ *
+ *     public static void main(String[] args) throws Exception {
+ *         PassFailJFrame passFail = new PassFailJFrame(INSTRUCTIONS);
+ *
+ *         SwingUtilities.invokeAndWait(() -> createTestUI());
+ *
+ *         passFail.awaitAndCheck();
+ *     }
+ *
+ *     private static void createTestUI() {
+ *         JFrame testUI = new JFrame("Test UI");
+ *         testUI.setSize(250, 150);
+ *         PassFailJFrame.addTestWindow(testUI);
+ *         PassFailJFrame.positionTestWindow(testUI, PassFailJFrame.Position.HORIZONTAL);
+ *         testUI.setVisible(true);
+ *     }
+ * }
+ * }
+ *

+ * Use methods of the {@code Builder} class or constructors of the + * {@code PassFailJFrame} class to control other parameters: + *

    + *
  • the title of the instruction UI,
  • + *
  • the timeout of the test,
  • + *
  • the size of the instruction UI via rows and columns, and
  • + *
  • to enable screenshots.
  • + *
+ */ public class PassFailJFrame { private static final String TITLE = "Test Instruction Frame"; @@ -60,16 +157,33 @@ * Prefix for the user-provided failure reason. */ private static final String FAILURE_REASON = "Failure Reason:\n"; + /** + * The failure reason message when the user didn't provide one. + */ + private static final String EMPTY_REASON = "(no reason provided)"; private static final List windowList = new ArrayList<>(); - private static final Timer timer = new Timer(0, null); + private static final CountDownLatch latch = new CountDownLatch(1); - private static volatile boolean failed; - private static volatile boolean timeout; - private static volatile String testFailedReason; + private static TimeoutHandler timeoutHandler; + + /** + * The description of why the test fails. + *

+ * Note: do not use this field directly, + * use the {@link #setFailureReason(String) setFailureReason} and + * {@link #getFailureReason() getFailureReason} methods to modify and + * to read its value. + */ + private static String failureReason; + + private static final AtomicInteger imgCounter = new AtomicInteger(0); + private static JFrame frame; + private static Robot robot; + public enum Position {HORIZONTAL, VERTICAL, TOP_LEFT_CORNER} public PassFailJFrame(String instructions) throws InterruptedException, @@ -114,69 +228,143 @@ public PassFailJFrame(String title, String instructions, long testTimeOut, int rows, int columns) throws InterruptedException, InvocationTargetException { + this(title, instructions, testTimeOut, rows, columns, false); + } + + /** + * Constructs a JFrame with a given title & serves as test instructional + * frame where the user follows the specified test instruction in order + * to test the test case & mark the test pass or fail. If the expected + * result is seen then the user click on the 'Pass' button else click + * on the 'Fail' button and the reason for the failure should be + * specified in the JDialog JTextArea. + *

+ * The test instruction frame also provides a way for the tester to take + * a screenshot (full screen or individual frame) if this feature + * is enabled by passing {@code true} as {@code enableScreenCapture} + * parameter. + * + * @param title title of the Frame. + * @param instructions the instruction for the tester on how to test + * and what is expected (pass) and what is not + * expected (fail). + * @param testTimeOut test timeout where time is specified in minutes. + * @param rows number of visible rows of the JTextArea where the + * instruction is show. + * @param columns Number of columns of the instructional + * JTextArea + * @param enableScreenCapture if set to true, 'Capture Screen' button & its + * associated UIs are added to test instruction + * frame + * @throws InterruptedException exception thrown when thread is + * interrupted + * @throws InvocationTargetException if an exception is thrown while + * creating the test instruction frame on + * EDT + */ + public PassFailJFrame(String title, String instructions, long testTimeOut, + int rows, int columns, + boolean enableScreenCapture) + throws InterruptedException, InvocationTargetException { + invokeOnEDT(() -> createUI(title, instructions, + testTimeOut, + rows, columns, + enableScreenCapture)); + } + + private PassFailJFrame(Builder builder) throws InterruptedException, + InvocationTargetException { + this(builder.title, builder.instructions, builder.testTimeOut, + builder.rows, builder.columns, builder.screenCapture); + + if (builder.windowCreator != null) { + invokeOnEDT(() -> + builder.testWindows = builder.windowCreator.createTestUI()); + } + + if (builder.testWindows != null) { + addTestWindow(builder.testWindows); + builder.testWindows + .forEach(w -> w.addWindowListener(windowClosingHandler)); + + if (builder.positionWindows != null) { + positionInstructionFrame(builder.position); + invokeOnEDT(() -> { + builder.positionWindows + .positionTestWindows(unmodifiableList(builder.testWindows), + builder.instructionUIHandler); + + windowList.forEach(w -> w.setVisible(true)); + }); + } else if (builder.testWindows.size() == 1) { + Window window = builder.testWindows.get(0); + positionTestWindow(window, builder.position); + window.setVisible(true); + } else { + positionTestWindow(null, builder.position); + } + } + } + + /** + * Performs an operation on EDT. If called on EDT, invokes {@code run} + * directly, otherwise wraps into {@code invokeAndWait}. + * + * @param doRun an operation to run on EDT + * @throws InterruptedException if we're interrupted while waiting for + * the event dispatching thread to finish executing + * {@code doRun.run()} + * @throws InvocationTargetException if an exception is thrown while + * running {@code doRun} + * @see javax.swing.SwingUtilities#invokeAndWait(Runnable) + */ + private static void invokeOnEDT(Runnable doRun) + throws InterruptedException, InvocationTargetException { if (isEventDispatchThread()) { - createUI(title, instructions, testTimeOut, rows, columns); + doRun.run(); } else { - invokeAndWait(() -> createUI(title, instructions, testTimeOut, - rows, columns)); + invokeAndWait(doRun); } } private static void createUI(String title, String instructions, - long testTimeOut, int rows, int columns) { + long testTimeOut, int rows, int columns, + boolean enableScreenCapture) { frame = new JFrame(title); frame.setLayout(new BorderLayout()); - JTextArea instructionsText = new JTextArea(instructions, rows, columns); - instructionsText.setEditable(false); - instructionsText.setLineWrap(true); - - long tTimeout = TimeUnit.MINUTES.toMillis(testTimeOut); - - final JLabel testTimeoutLabel = new JLabel(String.format("Test " + - "timeout: %s", convertMillisToTimeStr(tTimeout)), JLabel.CENTER); - final long startTime = System.currentTimeMillis(); - timer.setDelay(1000); - timer.addActionListener((e) -> { - long leftTime = tTimeout - (System.currentTimeMillis() - startTime); - if ((leftTime < 0) || failed) { - timer.stop(); - testFailedReason = FAILURE_REASON - + "Timeout User did not perform testing."; - timeout = true; - latch.countDown(); - } - testTimeoutLabel.setText(String.format("Test timeout: %s", convertMillisToTimeStr(leftTime))); - }); - timer.start(); + + JLabel testTimeoutLabel = new JLabel("", JLabel.CENTER); + timeoutHandler = new TimeoutHandler(testTimeoutLabel, testTimeOut); frame.add(testTimeoutLabel, BorderLayout.NORTH); - frame.add(new JScrollPane(instructionsText), BorderLayout.CENTER); + + JTextComponent text = instructions.startsWith("") + ? configureHTML(instructions, rows, columns) + : configurePlainText(instructions, rows, columns); + text.setEditable(false); + + frame.add(new JScrollPane(text), BorderLayout.CENTER); JButton btnPass = new JButton("Pass"); btnPass.addActionListener((e) -> { latch.countDown(); - timer.stop(); + timeoutHandler.stop(); }); JButton btnFail = new JButton("Fail"); btnFail.addActionListener((e) -> { - getFailureReason(); - timer.stop(); + requestFailureReason(); + timeoutHandler.stop(); }); JPanel buttonsPanel = new JPanel(); buttonsPanel.add(btnPass); buttonsPanel.add(btnFail); - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - super.windowClosing(e); - testFailedReason = FAILURE_REASON - + "User closed the instruction Frame"; - failed = true; - latch.countDown(); - } - }); + if (enableScreenCapture) { + buttonsPanel.add(createCapturePanel()); + } + + frame.addWindowListener(windowClosingHandler); frame.add(buttonsPanel, BorderLayout.SOUTH); frame.pack(); @@ -184,14 +372,280 @@ windowList.add(frame); } - private static String convertMillisToTimeStr(long millis) { - if (millis < 0) { - return "00:00:00"; - } - long hours = millis / 3_600_000; - long minutes = (millis - hours * 3_600_000) / 60_000; - long seconds = (millis - hours * 3_600_000 - minutes * 60_000) / 1_000; - return String.format("%02d:%02d:%02d", hours, minutes, seconds); + private static JTextComponent configurePlainText(String instructions, + int rows, int columns) { + JTextArea text = new JTextArea(instructions, rows, columns); + text.setLineWrap(true); + text.setWrapStyleWord(true); + return text; + } + + private static JTextComponent configureHTML(String instructions, + int rows, int columns) { + JEditorPane text = new JEditorPane("text/html", instructions); + text.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, + Boolean.TRUE); + // Set preferred size as if it were JTextArea + text.setPreferredSize(new JTextArea(rows, columns).getPreferredSize()); + + HTMLEditorKit kit = (HTMLEditorKit) text.getEditorKit(); + StyleSheet styles = kit.getStyleSheet(); + // Reduce the default margins + styles.addRule("ol, ul { margin-left-ltr: 20; margin-left-rtl: 20 }"); + // Make the size of code blocks the same as other text + styles.addRule("code { font-size: inherit }"); + + return text; + } + + + /** + * Creates one or more windows for test UI. + */ + @FunctionalInterface + public interface WindowCreator { + /** + * Creates one or more windows for test UI. + * This method is called by the framework on the EDT. + * @return a list of windows. + */ + List createTestUI(); + } + + /** + * Positions test UI windows. + */ + @FunctionalInterface + public interface PositionWindows { + /** + * Positions test UI windows. + * This method is called by the framework on the EDT after + * the instruction UI frame was positioned on the screen. + *

+ * The list of the test windows contains the windows + * that were passed to the framework via + * {@link Builder#testUI(WindowCreator) testUI} method. + * + * @param testWindows the list of test windows + * @param instructionUI information about the instruction frame + */ + void positionTestWindows(List testWindows, + InstructionUI instructionUI); + } + + /** + * Provides information about the instruction frame. + */ + public interface InstructionUI { + /** + * {@return the location of the instruction frame} + */ + Point getLocation(); + + /** + * {@return the size of the instruction frame} + */ + Dimension getSize(); + + /** + * {@return the bounds of the instruction frame} + */ + Rectangle getBounds(); + + /** + * Allows to change the location of the instruction frame. + * + * @param location the new location of the instruction frame + */ + void setLocation(Point location); + + /** + * Allows to change the location of the instruction frame. + * + * @param x the x coordinate of the new location + * @param y the y coordinate of the new location + */ + void setLocation(int x, int y); + + /** + * Returns the specified position that was used to set + * the initial location of the instruction frame. + * + * @return the specified position + * + * @see Position + */ + Position getPosition(); + } + + + private static final class TimeoutHandler implements ActionListener { + private final long endTime; + + private final Timer timer; + + private final JLabel label; + + public TimeoutHandler(final JLabel label, final long testTimeOut) { + endTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(testTimeOut); + + this.label = label; + + timer = new Timer(1000, this); + timer.start(); + updateTime(testTimeOut); + } + + @Override + public void actionPerformed(ActionEvent e) { + long leftTime = endTime - System.currentTimeMillis(); + if (leftTime < 0) { + timer.stop(); + setFailureReason(FAILURE_REASON + + "Timeout - User did not perform testing."); + latch.countDown(); + } + updateTime(leftTime); + } + + private void updateTime(final long leftTime) { + if (leftTime < 0) { + label.setText("Test timeout: 00:00:00"); + return; + } + long hours = leftTime / 3_600_000; + long minutes = (leftTime - hours * 3_600_000) / 60_000; + long seconds = (leftTime - hours * 3_600_000 - minutes * 60_000) / 1_000; + label.setText(String.format("Test timeout: %02d:%02d:%02d", + hours, minutes, seconds)); + } + + public void stop() { + timer.stop(); + } + } + + + private static final class WindowClosingHandler extends WindowAdapter { + @Override + public void windowClosing(WindowEvent e) { + setFailureReason(FAILURE_REASON + + "User closed a window"); + latch.countDown(); + } + } + + private static final WindowListener windowClosingHandler = + new WindowClosingHandler(); + + + private static JComponent createCapturePanel() { + JComboBox screenShortType = new JComboBox<>(CaptureType.values()); + + JButton capture = new JButton("ScreenShot"); + capture.addActionListener((e) -> + captureScreen((CaptureType) screenShortType.getSelectedItem())); + + JPanel panel = new JPanel(); + panel.add(screenShortType); + panel.add(capture); + return panel; + } + + private enum CaptureType { + FULL_SCREEN("Capture Full Screen"), + WINDOWS("Capture Individual Frame"); + + private final String type; + CaptureType(String type) { + this.type = type; + } + + @Override + public String toString() { + return type; + } + } + + private static Robot createRobot() { + if (robot == null) { + try { + robot = new Robot(); + } catch (AWTException e) { + String errorMsg = "Failed to create an instance of Robot."; + JOptionPane.showMessageDialog(frame, errorMsg, "Failed", + JOptionPane.ERROR_MESSAGE); + forceFail(errorMsg + e.getMessage()); + } + } + return robot; + } + + private static void captureScreen(Rectangle bounds) { + Robot robot = createRobot(); + + List imageList = robot.createMultiResolutionScreenCapture(bounds) + .getResolutionVariants(); + Image image = imageList.get(imageList.size() - 1); + + File file = new File("CaptureScreen_" + + imgCounter.incrementAndGet() + ".png"); + try { + ImageIO.write((RenderedImage) image, "png", file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static void captureScreen(CaptureType type) { + switch (type) { + case FULL_SCREEN: + Arrays.stream(GraphicsEnvironment.getLocalGraphicsEnvironment() + .getScreenDevices()) + .map(GraphicsDevice::getDefaultConfiguration) + .map(GraphicsConfiguration::getBounds) + .forEach(PassFailJFrame::captureScreen); + break; + + case WINDOWS: + windowList.stream() + .filter(Window::isShowing) + .map(Window::getBounds) + .forEach(PassFailJFrame::captureScreen); + break; + + default: + throw new IllegalStateException("Unexpected value of capture type"); + } + + JOptionPane.showMessageDialog(frame, + "Screen Captured Successfully", + "Screen Capture", + JOptionPane.INFORMATION_MESSAGE); + } + + /** + * Sets the failure reason which describes why the test fails. + * This method ensures the {@code failureReason} field does not change + * after it's set to a non-{@code null} value. + * @param reason the description of why the test fails + * @throws IllegalArgumentException if the {@code reason} parameter + * is {@code null} + */ + private static synchronized void setFailureReason(final String reason) { + if (reason == null) { + throw new IllegalArgumentException("The failure reason must not be null"); + } + if (failureReason == null) { + failureReason = reason; + } + } + + /** + * {@return the description of why the test fails} + */ + private static synchronized String getFailureReason() { + return failureReason; } /** @@ -212,32 +666,18 @@ latch.await(); invokeAndWait(PassFailJFrame::disposeWindows); - if (timeout) { - throw new RuntimeException(testFailedReason); - } - - if (failed) { - throw new RuntimeException("Test failed! : " + testFailedReason); + String failure = getFailureReason(); + if (failure != null) { + throw new RuntimeException(failure); } System.out.println("Test passed!"); } /** - * Dispose all the window(s) i,e both the test instruction frame and - * the window(s) that is added via addTestWindow(Window testWindow) - */ - private static synchronized void disposeWindows() { - for (Window win : windowList) { - win.dispose(); - } - } - - /** - * Read the test failure reason and add the reason to the test result - * example in the jtreg .jtr file. + * Requests the description of the test failure reason from the tester. */ - private static void getFailureReason() { + private static void requestFailureReason() { final JDialog dialog = new JDialog(frame, "Test Failure ", true); dialog.setTitle("Failure reason"); JPanel jPanel = new JPanel(new BorderLayout()); @@ -245,7 +685,9 @@ JButton okButton = new JButton("OK"); okButton.addActionListener((ae) -> { - testFailedReason = FAILURE_REASON + jTextArea.getText(); + String text = jTextArea.getText(); + setFailureReason(FAILURE_REASON + + (!text.isEmpty() ? text : EMPTY_REASON)); dialog.setVisible(false); }); @@ -260,12 +702,53 @@ dialog.pack(); dialog.setVisible(true); - failed = true; + // Ensure the test fails even if the dialog is closed + // without clicking the OK button + setFailureReason(FAILURE_REASON + EMPTY_REASON); + dialog.dispose(); latch.countDown(); } /** + * Disposes of all the windows. It disposes of the test instruction frame + * and all other windows added via {@link #addTestWindow(Window)}. + */ + private static synchronized void disposeWindows() { + windowList.forEach(Window::dispose); + } + + private static void positionInstructionFrame(final Position position) { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + // Get the screen insets to position the frame by taking into + // account the location of taskbar or menu bar on screen. + GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .getDefaultConfiguration(); + Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + + switch (position) { + case HORIZONTAL: + int newX = ((screenSize.width / 2) - frame.getWidth()); + frame.setLocation((newX + screenInsets.left), + (frame.getY() + screenInsets.top)); + break; + + case VERTICAL: + int newY = ((screenSize.height / 2) - frame.getHeight()); + frame.setLocation((frame.getX() + screenInsets.left), + (newY + screenInsets.top)); + break; + + case TOP_LEFT_CORNER: + frame.setLocation(screenInsets.left, screenInsets.top); + break; + } + syncLocationToWindowManager(); + } + + /** * Approximately positions the instruction frame relative to the test * window as specified by the {@code position} parameter. If {@code testWindow} * is {@code null}, only the instruction frame is positioned according to @@ -295,40 +778,23 @@ * */ public static void positionTestWindow(Window testWindow, Position position) { - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - - // Get the screen insets to position the frame by taking into - // account the location of taskbar/menubars on screen. - GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment() - .getDefaultScreenDevice().getDefaultConfiguration(); - Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + positionInstructionFrame(position); - if (position.equals(Position.HORIZONTAL)) { - int newX = ((screenSize.width / 2) - frame.getWidth()); - frame.setLocation((newX + screenInsets.left), - (frame.getY() + screenInsets.top)); - syncLocationToWindowManager(); - if (testWindow != null) { - testWindow.setLocation((frame.getX() + frame.getWidth() + 5), - frame.getY()); - } - } else if (position.equals(Position.VERTICAL)) { - int newY = ((screenSize.height / 2) - frame.getHeight()); - frame.setLocation((frame.getX() + screenInsets.left), - (newY + screenInsets.top)); - syncLocationToWindowManager(); - if (testWindow != null) { - testWindow.setLocation(frame.getX(), - (frame.getY() + frame.getHeight() + 5)); - } - } else if (position.equals(Position.TOP_LEFT_CORNER)) { - frame.setLocation(screenInsets.left, screenInsets.top); - syncLocationToWindowManager(); - if (testWindow != null) { - testWindow.setLocation((frame.getX() + frame.getWidth() + 5), - frame.getY()); + if (testWindow != null) { + switch (position) { + case HORIZONTAL: + case TOP_LEFT_CORNER: + testWindow.setLocation((frame.getX() + frame.getWidth() + 5), + frame.getY()); + break; + + case VERTICAL: + testWindow.setLocation(frame.getX(), + (frame.getY() + frame.getHeight() + 5)); + break; } } + // make instruction frame visible after updating // frame & window positions frame.setVisible(true); @@ -368,13 +834,7 @@ throws InterruptedException, InvocationTargetException { final Rectangle[] bounds = {null}; - if (isEventDispatchThread()) { - bounds[0] = frame != null ? frame.getBounds() : null; - } else { - invokeAndWait(() -> { - bounds[0] = frame != null ? frame.getBounds() : null; - }); - } + invokeOnEDT(() -> bounds[0] = frame != null ? frame.getBounds() : null); return bounds[0]; } @@ -390,6 +850,16 @@ } /** + * Adds a collection of test windows to the windowList to be disposed of + * when the test completes. + * + * @param testWindows the collection of test windows to be disposed of + */ + public static synchronized void addTestWindow(Collection testWindows) { + windowList.addAll(testWindows); + } + + /** * Forcibly pass the test. *

The sample usage: *


@@ -417,8 +887,177 @@
      * @param reason the reason why the test is failed
      */
     public static void forceFail(String reason) {
-        failed = true;
-        testFailedReason = FAILURE_REASON + reason;
+        setFailureReason(FAILURE_REASON + reason);
         latch.countDown();
     }
+
+    public static final class Builder {
+        private String title;
+        private String instructions;
+        private long testTimeOut;
+        private int rows;
+        private int columns;
+        private boolean screenCapture;
+
+        private List testWindows;
+        private WindowCreator windowCreator;
+        private PositionWindows positionWindows;
+        private InstructionUI instructionUIHandler;
+
+        private Position position;
+
+        public Builder title(String title) {
+            this.title = title;
+            return this;
+        }
+
+        public Builder instructions(String instructions) {
+            this.instructions = instructions;
+            return this;
+        }
+
+        public Builder testTimeOut(long testTimeOut) {
+            this.testTimeOut = testTimeOut;
+            return this;
+        }
+
+        public Builder rows(int rows) {
+            this.rows = rows;
+            return this;
+        }
+
+        public Builder columns(int columns) {
+            this.columns = columns;
+            return this;
+        }
+
+        public Builder screenCapture() {
+            this.screenCapture = true;
+            return this;
+        }
+
+        public Builder testUI(Window window) {
+            return testUI(List.of(window));
+        }
+
+        public Builder testUI(Window... windows) {
+            return testUI(List.of(windows));
+        }
+
+        public Builder testUI(List windows) {
+            if (windows == null) {
+                throw new IllegalArgumentException("The list of windows can't be null");
+            }
+            if (windows.stream()
+                       .anyMatch(Objects::isNull)) {
+                throw new IllegalArgumentException("The windows list can't contain null");
+            }
+
+            if (windowCreator != null) {
+                throw new IllegalStateException("windowCreator is already set");
+            }
+            this.testWindows = windows;
+            return this;
+        }
+
+        public Builder testUI(WindowCreator windowCreator) {
+            if (windowCreator == null) {
+                throw new IllegalArgumentException("The window creator can't be null");
+            }
+            if (testWindows != null) {
+                throw new IllegalStateException("testWindows are already set");
+            }
+            this.windowCreator = windowCreator;
+            return this;
+        }
+
+        public Builder positionTestUI(PositionWindows positionWindows) {
+            this.positionWindows = positionWindows;
+            return this;
+        }
+
+        public Builder position(Position position) {
+            this.position = position;
+            return this;
+        }
+
+        public PassFailJFrame build() throws InterruptedException,
+                InvocationTargetException {
+            validate();
+            return new PassFailJFrame(this);
+        }
+
+        private void validate() {
+            if (title == null) {
+                title = TITLE;
+            }
+
+            if (instructions == null || instructions.isEmpty()) {
+                throw new IllegalStateException("Please provide the test " +
+                        "instructions for this manual test");
+            }
+
+            if (testTimeOut == 0L) {
+                testTimeOut = TEST_TIMEOUT;
+            }
+
+            if (rows == 0) {
+                rows = ROWS;
+            }
+
+            if (columns == 0) {
+                columns = COLUMNS;
+            }
+
+            if (position == null
+                && (testWindows != null || windowCreator != null)) {
+
+                position = Position.HORIZONTAL;
+            }
+
+            if (positionWindows != null) {
+                if (testWindows == null && windowCreator == null) {
+                    throw new IllegalStateException("To position windows, "
+                            + "provide an a list of windows to the builder");
+                }
+                instructionUIHandler = new InstructionUIHandler();
+            }
+        }
+
+        private final class InstructionUIHandler implements InstructionUI {
+            @Override
+            public Point getLocation() {
+                return frame.getLocation();
+            }
+
+            @Override
+            public Dimension getSize() {
+                return frame.getSize();
+            }
+
+            @Override
+            public Rectangle getBounds() {
+                return frame.getBounds();
+            }
+
+            @Override
+            public void setLocation(Point location) {
+                setLocation(location.x, location.y);
+            }
+
+            @Override
+            public void setLocation(int x, int y) {
+                frame.setLocation(x, y);
+            }
+
+            @Override
+            public Position getPosition() {
+                return position;
+            }
+        }
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/foreign/TestClassLoaderFindNative.java openjdk-21-21.0.2+13/test/jdk/java/foreign/TestClassLoaderFindNative.java
--- openjdk-21-21.0.1+12/test/jdk/java/foreign/TestClassLoaderFindNative.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/foreign/TestClassLoaderFindNative.java	2024-01-16 16:19:00.000000000 +0000
@@ -31,9 +31,10 @@
 import java.lang.foreign.Arena;
 import java.lang.foreign.MemorySegment;
 import java.lang.foreign.SymbolLookup;
+import java.nio.ByteOrder;
 import org.testng.annotations.Test;
 
-import static java.lang.foreign.ValueLayout.JAVA_BYTE;
+import static java.lang.foreign.ValueLayout.JAVA_INT;
 import static org.testng.Assert.*;
 
 // FYI this test is run on 64-bit platforms only for now,
@@ -58,8 +59,8 @@
 
     @Test
     public void testVariableSymbolLookup() {
-        MemorySegment segment = SymbolLookup.loaderLookup().find("c").get().reinterpret(1);
-        assertEquals(segment.get(JAVA_BYTE, 0), 42);
+        MemorySegment segment = SymbolLookup.loaderLookup().find("c").get().reinterpret(4);
+        assertEquals(segment.get(JAVA_INT, 0), 42);
     }
 
     @Test
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/foreign/TestIllegalLink.java openjdk-21-21.0.2+13/test/jdk/java/foreign/TestIllegalLink.java
--- openjdk-21-21.0.1+12/test/jdk/java/foreign/TestIllegalLink.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/foreign/TestIllegalLink.java	2024-01-16 16:19:00.000000000 +0000
@@ -54,6 +54,7 @@
 public class TestIllegalLink extends NativeTestHelper {
 
     private static final boolean IS_SYSV = CABI.current() == CABI.SYS_V;
+    private static final boolean IS_LE = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN;
 
     private static final MemorySegment DUMMY_TARGET = MemorySegment.ofAddress(1);
     private static final MethodHandle DUMMY_TARGET_MH = MethodHandles.empty(MethodType.methodType(void.class));
@@ -113,27 +114,27 @@
             {
                     FunctionDescriptor.of(MemoryLayout.sequenceLayout(2, C_INT)),
                     NO_OPTIONS,
-                    "Unsupported layout: [2:i4]"
+                    IS_LE ? "Unsupported layout: [2:i4]" : "Unsupported layout: [2:I4]"
             },
             {
                     FunctionDescriptor.ofVoid(MemoryLayout.sequenceLayout(2, C_INT)),
                     NO_OPTIONS,
-                    "Unsupported layout: [2:i4]"
+                    IS_LE ? "Unsupported layout: [2:i4]" : "Unsupported layout: [2:I4]"
             },
             {
                     FunctionDescriptor.ofVoid(C_INT.withByteAlignment(2)),
                     NO_OPTIONS,
-                    "Unsupported layout: 2%i4"
+                    IS_LE ? "Unsupported layout: 2%i4" : "Unsupported layout: 2%I4"
             },
             {
                     FunctionDescriptor.ofVoid(C_POINTER.withByteAlignment(2)),
                     NO_OPTIONS,
-                    "Unsupported layout: 2%a8"
+                    IS_LE ? "Unsupported layout: 2%a8" : "Unsupported layout: 2%A8"
             },
             {
                     FunctionDescriptor.ofVoid(ValueLayout.JAVA_CHAR.withByteAlignment(4)),
                     NO_OPTIONS,
-                    "Unsupported layout: 4%c2"
+                    IS_LE ? "Unsupported layout: 4%c2" : "Unsupported layout: 4%C2"
             },
             {
                     FunctionDescriptor.ofVoid(MemoryLayout.structLayout(
@@ -142,7 +143,7 @@
                             C_INT.withName("z").withByteAlignment(1)
                             ).withByteAlignment(1)),
                     NO_OPTIONS,
-                    "Unsupported layout: 1%s2"
+                    IS_LE ? "Unsupported layout: 1%s2" : "Unsupported layout: 1%S2"
             },
             {
                     FunctionDescriptor.ofVoid(MemoryLayout.structLayout(
@@ -152,7 +153,7 @@
                                 C_INT.withName("z").withByteAlignment(1)
                             ))),
                     NO_OPTIONS,
-                    "Unsupported layout: 1%s2"
+                    IS_LE ? "Unsupported layout: 1%s2" : "Unsupported layout: 1%S2"
             },
             {
                     FunctionDescriptor.ofVoid(MemoryLayout.structLayout(
@@ -160,7 +161,7 @@
                                 C_INT.withByteAlignment(1)
                             ))),
                     NO_OPTIONS,
-                    "Unsupported layout: 1%i4"
+                    IS_LE ? "Unsupported layout: 1%i4" : "Unsupported layout: 1%I4"
             },
             {
                     FunctionDescriptor.ofVoid(MemoryLayout.structLayout(
@@ -173,17 +174,17 @@
             {
                     FunctionDescriptor.of(C_INT.withOrder(nonNativeOrder())),
                     NO_OPTIONS,
-                    "Unsupported layout: I4"
+                    IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4"
             },
             {
                     FunctionDescriptor.of(MemoryLayout.structLayout(C_INT.withOrder(nonNativeOrder()))),
                     NO_OPTIONS,
-                    "Unsupported layout: I4"
+                    IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4"
             },
             {
                     FunctionDescriptor.of(MemoryLayout.structLayout(MemoryLayout.sequenceLayout(C_INT.withOrder(nonNativeOrder())))),
                     NO_OPTIONS,
-                    "Unsupported layout: I4"
+                    IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4"
             },
             {
                     FunctionDescriptor.ofVoid(MemoryLayout.structLayout(
@@ -227,5 +228,4 @@
                 ? ByteOrder.BIG_ENDIAN
                 : ByteOrder.LITTLE_ENDIAN;
     }
-
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/foreign/UpcallTestHelper.java openjdk-21-21.0.2+13/test/jdk/java/foreign/UpcallTestHelper.java
--- openjdk-21-21.0.1+12/test/jdk/java/foreign/UpcallTestHelper.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/foreign/UpcallTestHelper.java	2024-01-16 16:19:00.000000000 +0000
@@ -21,13 +21,12 @@
  * questions.
  */
 
-import jdk.test.lib.Utils;
+import jdk.test.lib.process.ProcessTools;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -57,22 +56,15 @@
         assert !target.isArray();
 
         List command = new ArrayList<>(List.of(
-            Paths.get(Utils.TEST_JDK)
-                    .resolve("bin")
-                    .resolve("java")
-                    .toAbsolutePath()
-                    .toString(),
             "--enable-preview",
             "--enable-native-access=ALL-UNNAMED",
             "-Djava.library.path=" + System.getProperty("java.library.path"),
             "-Djdk.internal.foreign.UpcallLinker.USE_SPEC=" + useSpec,
-            "-cp", Utils.TEST_CLASS_PATH,
             target.getName()
         ));
         command.addAll(Arrays.asList(programArgs));
-        Process process = new ProcessBuilder()
-            .command(command)
-            .start();
+
+        Process process = ProcessTools.createTestJvm(command).start();
 
         int result = process.waitFor();
         assertNotEquals(result, 0);
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java openjdk-21-21.0.2+13/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java
--- openjdk-21-21.0.1+12/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java	2024-01-16 16:19:00.000000000 +0000
@@ -305,5 +305,4 @@
         public static final AddressLayout C_POINTER = SharedUtils.C_POINTER;
 
     }
-
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java openjdk-21-21.0.2+13/test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java
--- openjdk-21-21.0.1+12/test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java	2024-01-16 16:19:00.000000000 +0000
@@ -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.
+ */
+
+/* @test
+ * @bug 8316156
+ * @summary Ensure ByteArrayInputStream.transferTo does not cause direct memory
+ *          to overflow MaxDirectMemorySize
+ * @run junit/othervm -XX:MaxDirectMemorySize=5M ChunkedTransferTo
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Random;
+
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+import static java.nio.file.StandardOpenOption.*;
+
+import org.junit.jupiter.api.Test;
+
+public class ChunkedTransferTo {
+    // this value must exceed MaxDirectMemorySize
+    private static final int SIZE = 10_000_000;
+
+    @Test
+    public void byteArrayInputStream() throws IOException {
+        byte[] src = new byte[SIZE];
+        Random rnd = new Random(System.nanoTime());
+        rnd.nextBytes(src);
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(src)) {
+            Path target = Files.createTempFile("SNA", "FU");
+            FileChannel fc = FileChannel.open(target, CREATE, WRITE);
+            bais.transferTo(Channels.newOutputStream(fc));
+            byte[] dst = new byte[SIZE + 1];
+            try (FileInputStream fis = new FileInputStream(target.toFile())) {
+                int n = -1;
+                if ((n = fis.read(dst)) != SIZE)
+                    throw new RuntimeException(n + " != " + SIZE);
+            }
+            Files.delete(target);
+            if (!Arrays.equals(src, 0, SIZE, dst, 0, SIZE))
+                throw new RuntimeException("Arrays are not equal");
+        } catch (OutOfMemoryError oome) {
+            throw new RuntimeException(oome);
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/io/File/TempDirDoesNotExist.java openjdk-21-21.0.2+13/test/jdk/java/io/File/TempDirDoesNotExist.java
--- openjdk-21-21.0.1+12/test/jdk/java/io/File/TempDirDoesNotExist.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/io/File/TempDirDoesNotExist.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -25,91 +25,126 @@
  * @bug 8290313
  * @library /test/lib
  * @summary Produce warning when user specified java.io.tmpdir directory doesn't exist
+ * @run junit TempDirDoesNotExist
  */
 
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
 
 import java.io.File;
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.List;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
-public class TempDirDoesNotExist {
-    final static String ioWarningMsg = "WARNING: java.io.tmpdir directory does not exist";
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
-    public static void main(String... args) throws Exception {
+public class TempDirDoesNotExist {
+    final static String WARNING = "WARNING: java.io.tmpdir directory does not exist";
 
-        String userDir = System.getProperty("user.home");
-        String timeStamp = System.currentTimeMillis() + "";
-        String tempDir = Path.of(userDir,"non-existing-", timeStamp).toString();
+    private static final String USER_DIR = System.getProperty("user.home");
 
+    //
+    // This class is spawned to test combinations of parameters.
+    //
+    public static void main(String... args) throws IOException {
         for (String arg : args) {
-            if (arg.equals("io")) {
-                try {
-                    File.createTempFile("prefix", ".suffix");
-                } catch (Exception e) {
-                    e.printStackTrace();
+            switch (arg) {
+                case "io" -> {
+                    File file = null;
+                    try {
+                        file = File.createTempFile("prefix", ".suffix");
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    } finally {
+                        if (file != null && file.exists())
+                            if (!file.delete())
+                                throw new RuntimeException(file + " not deleted");
+                    }
                 }
-            } else if (arg.equals("nio")) {
-                try {
-                    Files.createTempFile("prefix", ".suffix");
-                } catch (Exception e) {
-                    e.printStackTrace();
+                case "nio" -> {
+                Path path = null;
+                    try {
+                        path = Files.createTempFile("prefix", ".suffix");
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    } finally {
+                        if (path != null)
+                            if (!Files.deleteIfExists(path))
+                                throw new RuntimeException(path + " not deleted");
+                    }
+                }
+                default -> {
+                    throw new RuntimeException("unknown case: " + arg);
                 }
-            } else {
-                throw new Exception("unknown case: " + arg);
             }
         }
+    }
 
-        if (args.length == 0) {
-            // standard test with default setting for java.io.tmpdir
-            testMessageNotExist(0, ioWarningMsg, "TempDirDoesNotExist", "io");
-            testMessageNotExist(0, ioWarningMsg, "TempDirDoesNotExist", "nio");
-
-            // valid custom java.io.tmpdir
-            testMessageNotExist(0, ioWarningMsg, "-Djava.io.tmpdir=" + userDir,
-                    "TempDirDoesNotExist", "io");
-            testMessageNotExist(0, ioWarningMsg, "-Djava.io.tmpdir=" + userDir,
-                    "TempDirDoesNotExist", "nio");
-
-            // invalid custom java.io.tmpdir
-            testMessageExist(0, ioWarningMsg, "-Djava.io.tmpdir=" + tempDir,
-                    "TempDirDoesNotExist", "io");
-            testMessageExist(0, ioWarningMsg, "-Djava.io.tmpdir=" + tempDir,
-                    "TempDirDoesNotExist", "nio");
-
-            // test with security manager
-            testMessageExist(0, ioWarningMsg, "-Djava.io.tmpdir=" + tempDir
-                            + " -Djava.security.manager",
-                    "TempDirDoesNotExist", "io");
-
-            testMessageExist(0, ioWarningMsg, "-Djava.io.tmpdir=" + tempDir
-                            + " -Djava.security.manager",
-                    "TempDirDoesNotExist", "nio");
-
-            // error message printed only once
-            testMessageCounter(0, "-Djava.io.tmpdir=" + tempDir,
-                    "TempDirDoesNotExist", "io", "nio");
-        }
+    private static String tempDir() {
+        String timeStamp = String.valueOf(System.currentTimeMillis());
+        return Path.of(USER_DIR, "non-existing-", timeStamp).toString();
+    }
+
+    public static Stream tempDirSource() {
+        return Stream.of(Arguments.of(List.of("-Djava.io.tmpdir=" + tempDir(),
+                                              "TempDirDoesNotExist", "io")),
+                         Arguments.of(List.of("-Djava.io.tmpdir=" + tempDir(),
+                                              "TempDirDoesNotExist", "nio")),
+                         Arguments.of(List.of("-Djava.io.tmpdir=" + tempDir() +
+                                              " -Djava.security.manager",
+                                              "TempDirDoesNotExist", "io")),
+                         Arguments.of(List.of("-Djava.io.tmpdir=" + tempDir() +
+                                              " -Djava.security.manager",
+                                              "TempDirDoesNotExist", "nio")));
+    }
+
+    public static Stream noTempDirSource() {
+        return Stream.of(Arguments.of(List.of("TempDirDoesNotExist", "io")),
+                         Arguments.of(List.of("TempDirDoesNotExist", "nio")),
+                         Arguments.of(List.of("-Djava.io.tmpdir=" + USER_DIR,
+                                              "TempDirDoesNotExist", "io")),
+                         Arguments.of(List.of("-Djava.io.tmpdir=" + USER_DIR,
+                                              "TempDirDoesNotExist", "nio")));
+    }
+
+    public static Stream counterSource() {
+        // standard test with default setting for java.io.tmpdir
+        return Stream.of(Arguments.of(List.of("-Djava.io.tmpdir=" + tempDir(),
+                                             "TempDirDoesNotExist",
+                                             "io", "nio")));
     }
 
-    private static void testMessageExist(int exitValue, String errorMsg, String... options) throws Exception {
-        ProcessTools.executeTestJvm(options).shouldContain(errorMsg)
-                .shouldHaveExitValue(exitValue);
+    @ParameterizedTest
+    @MethodSource("tempDirSource")
+    public void existingMessage(List options) throws Exception {
+       ProcessTools.executeTestJvm(options).shouldContain(WARNING)
+           .shouldHaveExitValue(0);
     }
 
-    private static void testMessageNotExist(int exitValue, String errorMsg,String... options) throws Exception {
-        ProcessTools.executeTestJvm(options).shouldNotContain(errorMsg).shouldHaveExitValue(exitValue);
+    @ParameterizedTest
+    @MethodSource("noTempDirSource")
+    public void nonexistentMessage(List options) throws Exception {
+        ProcessTools.executeTestJvm(options).shouldNotContain(WARNING)
+            .shouldHaveExitValue(0);
     }
 
-    private static void testMessageCounter(int exitValue,String... options) throws Exception {
+    @ParameterizedTest
+    @MethodSource("counterSource")
+    public void messageCounter(List options) throws Exception {
         OutputAnalyzer originalOutput = ProcessTools.executeTestJvm(options);
-        List list = originalOutput.asLines().stream().filter(line
-                -> line.equalsIgnoreCase(ioWarningMsg)).collect(Collectors.toList());
-        if (list.size() != 1 || originalOutput.getExitValue() != exitValue)
-            throw new Exception("counter of messages is not one, but " + list.size()
-                    + "\n" + originalOutput.asLines().toString() + "\n");
+        long count = originalOutput.asLines().stream().filter(
+                line -> line.equalsIgnoreCase(WARNING)).count();
+        assertEquals(1, count,
+                     "counter of messages is not one, but " + count +
+                     "\n" + originalOutput.asLines().toString());
+        int exitValue = originalOutput.getExitValue();
+        assertEquals(0, exitValue);
     }
-}
\ No newline at end of file
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/io/File/libGetXSpace.c openjdk-21-21.0.2+13/test/jdk/java/io/File/libGetXSpace.c
--- openjdk-21-21.0.1+12/test/jdk/java/io/File/libGetXSpace.c	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/io/File/libGetXSpace.c	2024-01-16 16:19:00.000000000 +0000
@@ -23,7 +23,7 @@
 #include 
 #include "jni.h"
 #include "jni_util.h"
-#ifdef _WIN64
+#ifdef WINDOWS
 #include 
 #include 
 #include 
@@ -42,7 +42,7 @@
 extern "C" {
 #endif
 
-#ifdef _WIN64
+#ifdef WINDOWS
 jboolean initialized = JNI_FALSE;
 BOOL(WINAPI * pfnGetDiskSpaceInformation)(LPCWSTR, LPVOID) = NULL;
 #endif
@@ -67,7 +67,7 @@
         return JNI_FALSE;
     }
 
-#ifdef _WIN64
+#ifdef WINDOWS
     if (initialized == JNI_FALSE) {
         initialized = JNI_TRUE;
         HMODULE hmod = GetModuleHandleW(L"kernel32");
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/io/FileDescriptor/Sync.java openjdk-21-21.0.2+13/test/jdk/java/io/FileDescriptor/Sync.java
--- openjdk-21-21.0.1+12/test/jdk/java/io/FileDescriptor/Sync.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/io/FileDescriptor/Sync.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8314120
+ * @summary Sanity test for FileDescriptor.sync
+ * @library /test/lib
+ * @run main Sync
+ */
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.SyncFailedException;
+import jdk.test.lib.thread.VThreadRunner;
+
+public class Sync {
+
+    static final String TEST_DIR = System.getProperty("test.dir", ".");
+    static final int TRIES = 10_000;
+
+    public static void testWith(File file) throws Exception {
+        try (FileOutputStream fos = new FileOutputStream(file)) {
+            FileDescriptor fd = fos.getFD();
+            for (int t = 0; t < TRIES; t++) {
+                fd.sync();
+            }
+        } catch (SyncFailedException sfe) {
+            // Can happen on some filesystems, print it in the log
+            System.out.println("Sync failed (acceptable)");
+            sfe.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        // Run on platform threads
+        System.out.println("With platform threads");
+        run();
+
+        // Run on virtual threads
+        System.out.println("With virtual threads");
+        VThreadRunner.run(Sync::run);
+
+        System.out.println("Complete");
+    }
+
+    private static class AutoDelete implements AutoCloseable {
+        private final File file;
+
+        public AutoDelete(File file) {
+            this.file = file;
+        }
+
+        public File file() {
+            return file;
+        }
+
+        @Override
+        public void close() throws Exception {
+            file.delete();
+        }
+    }
+
+    public static void run() throws Exception {
+        try (var w = new AutoDelete(new File(TEST_DIR, "FileDescriptorSync1"))) {
+            testWith(w.file());
+        }
+
+        try (var w = new AutoDelete(File.createTempFile("FileDescriptorSync2", "tmp"))) {
+            testWith(w.file());
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/ProcessHandle/InfoTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/ProcessHandle/InfoTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/ProcessHandle/InfoTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/ProcessHandle/InfoTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, 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,12 +39,13 @@
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
 
-import jdk.test.lib.Platform;
-import jdk.test.lib.Utils;
 import org.testng.Assert;
 import org.testng.TestNG;
 import org.testng.annotations.Test;
 
+import jdk.test.lib.Platform;
+import jdk.test.lib.Utils;
+
 /*
  * @test
  * @bug 8077350 8081566 8081567 8098852 8136597
@@ -81,7 +82,6 @@
     }
 
     // Main can be used to run the tests from the command line with only testng.jar.
-    @SuppressWarnings("raw_types")
     public static void main(String[] args) {
         Class[] testclass = {InfoTest.class};
         TestNG testng = new TestNG();
@@ -160,11 +160,7 @@
                     ProcessHandle.Info info = p1.info();
                     System.out.printf(" info: %s%n", info);
 
-                    if (info.user().isPresent()) {
-                        String user = info.user().get();
-                        Assert.assertNotNull(user, "User name");
-                        Assert.assertEquals(user, whoami, "User name");
-                    }
+                    assertUser(info);
 
                     Optional command = info.command();
                     if (command.isPresent()) {
@@ -291,11 +287,8 @@
                 ProcessHandle.Info info = p.info();
                 System.out.printf(" info: %s%n", info);
 
-                if (info.user().isPresent()) {
-                    String user = info.user().get();
-                    Assert.assertNotNull(user);
-                    Assert.assertEquals(user, whoami);
-                }
+                assertUser(info);
+
                 if (info.command().isPresent()) {
                     String command = info.command().get();
                     String expected = "sleep";
@@ -397,7 +390,7 @@
             Instant end = Instant.now().plusMillis(500L);
             while (end.isBefore(Instant.now())) {
                 // burn the cpu time checking the time
-                long x = r.nextLong();
+                r.nextLong();
             }
             if (self.info().totalCpuDuration().isPresent()) {
                 Duration totalCpu = self.info().totalCpuDuration().get();
@@ -410,6 +403,7 @@
             }
         }
     }
+
     /**
      * Check two Durations, the second should be greater than the first or
      * within the supplied Epsilon.
@@ -443,4 +437,31 @@
         pb.command(list);
         return pb.start();
     }
+
+    /**
+     * Asserts the expected process user.
+     *
+     * The Expected user is determined by creating a file and reading its owner, see static block above.
+     *
+     * On Windows, when run privileged as member of the Administrators group, this does not always
+     * work because new files can be owned by BUILTIN\Administrators instead, depending on system
+     * settings. In that case we resort to comparing System property user.name, which does not contain
+     * the domain name, though.
+     *
+     * @param info ProcessHanlde info object
+     */
+    static void assertUser(ProcessHandle.Info info) {
+        if (!info.user().isPresent()) {
+            return;
+        }
+        String user = info.user().get();
+        Assert.assertNotNull(user, "User name");
+        if (Platform.isWindows() && "BUILTIN\\Administrators".equals(whoami)) {
+            int bsi = user.lastIndexOf("\\");
+            Assert.assertEquals(bsi == -1 ? user : user.substring(bsi + 1),
+                    System.getProperty("user.name"), "User name");
+        } else {
+            Assert.assertEquals(user, whoami, "User name");
+        }
+    }
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/ProcessHandle/TreeTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/ProcessHandle/TreeTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/ProcessHandle/TreeTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/ProcessHandle/TreeTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, 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
@@ -444,6 +444,11 @@
                 Assert.assertEquals(0, count, "Extra processes in descendants");
             }
 
+            List subprocesses = getChildren(p1Handle);
+            printf(" children:  %s%n",
+                    subprocesses.stream().map(p -> p.pid())
+                    .collect(Collectors.toList()));
+
             Assert.assertEquals(getChildren(p1Handle).size(),
                     factor, "expected direct children");
             count = getDescendants(p1Handle).size();
@@ -451,9 +456,9 @@
             Assert.assertTrue(count >= totalChildren,
                     "expected at least " + totalChildren + ", actual: " + count);
 
-            List subprocesses = getDescendants(p1Handle);
+            List descSubprocesses = getDescendants(p1Handle);
             printf(" descendants:  %s%n",
-                    subprocesses.stream().map(p -> p.pid())
+                    descSubprocesses.stream().map(p -> p.pid())
                     .collect(Collectors.toList()));
 
             p1.getOutputStream().close();  // Close stdin for the controlling p1
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/ScopedValue/UnboundValueAfterOOME.java openjdk-21-21.0.2+13/test/jdk/java/lang/ScopedValue/UnboundValueAfterOOME.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/ScopedValue/UnboundValueAfterOOME.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/ScopedValue/UnboundValueAfterOOME.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023 Red Hat, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.NoSuchElementException;
+
+/*
+ * @test
+ * @bug 8319120
+ * @enablePreview
+ * @run main/othervm -Xmx10m UnboundValueAfterOOME
+ */
+public class UnboundValueAfterOOME {
+
+    static final Thread doRun = new Thread() {
+        public void run() {
+            try {
+                try {
+                    // Provoke the VM to throw an OutOfMemoryError
+                    java.util.Arrays.fill(new int[Integer.MAX_VALUE][], new int[Integer.MAX_VALUE]);
+                } catch (OutOfMemoryError e) {
+                    // Try to get() an unbound ScopedValue
+                    ScopedValue.newInstance().get();
+                }
+            } catch (NoSuchElementException e) {
+                System.out.println("OK");
+                return;
+            }
+            throw new RuntimeException("Expected NoSuchElementException");
+        }
+    };
+
+    public static void main(String [] args) throws Exception {
+        doRun.run();   // Run on this Thread
+        var job = new Thread(doRun);
+        job.start();   // Run on a new Thread
+        job.join();
+        doRun.start(); // Run on the Thread doRun
+        doRun.join();
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/String/RegionMatches.java openjdk-21-21.0.2+13/test/jdk/java/lang/String/RegionMatches.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/String/RegionMatches.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/String/RegionMatches.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 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
@@ -23,18 +23,34 @@
 
 /**
  * @test
- * @bug 4016509
- * @summary test regionMatches corner case
+ * @bug 4016509 8316879
+ * @summary test regionMatches corner cases
+ * @run junit RegionMatches
  */
 
+import java.io.UnsupportedEncodingException;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class RegionMatches {
 
-  public static void main (String args[]) throws Exception {
-      String s1="abc";
-      String s2="def";
+  private final String s1_LATIN1 = "abc";
+  private final String s2_LATIN1 = "def";
 
-      if (!s1.regionMatches(0,s2,0,Integer.MIN_VALUE))
-          throw new RuntimeException("Integer overflow in RegionMatches");
+  private final String s1_UTF16 = "\u041e\u0434\u043d\u0430\u0436\u0434\u044b";
+  private final String s2_UTF16 = "\u0432\u0441\u0442\u0443\u0434\u0435\u043d";
+
+  @Test
+  public void TestLATIN1() {
+      // Test for 4016509
+      boolean result = s1_LATIN1.regionMatches(0, s2_LATIN1, 0, Integer.MIN_VALUE);
+      assertTrue(result, "Integer overflow in RegionMatches when comparing LATIN1 strings");
+  }
+
+  @Test
+  public void TestUTF16() throws UnsupportedEncodingException{
+      // Test for 8316879
+      boolean result = s1_UTF16.regionMatches(0, s2_UTF16, 0, Integer.MIN_VALUE + 1);
+      assertTrue(result, "Integer overflow in RegionMatches when comparing UTF16 strings");
   }
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/META-INF/services/java.lang.System$LoggerFinder openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/META-INF/services/java.lang.System$LoggerFinder
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/META-INF/services/java.lang.System$LoggerFinder	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/META-INF/services/java.lang.System$LoggerFinder	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1 @@
+loggerfinder.SimpleLoggerFinder
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/PlatformRecursiveLoadingTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/PlatformRecursiveLoadingTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/PlatformRecursiveLoadingTest.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/PlatformRecursiveLoadingTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ * 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 8314263
+ * @summary Creating a logger while loading the Logger finder
+ *          triggers recursion and StackOverflowError
+ * @modules java.base/sun.util.logging java.base/jdk.internal.logger:+open
+ * @library ../lib
+ * @compile RecursiveLoadingTest.java SimpleLoggerFinder.java
+ * @run main/othervm PlatformRecursiveLoadingTest
+ */
+
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.LogRecord;
+
+import sun.util.logging.PlatformLogger;
+
+public class PlatformRecursiveLoadingTest {
+
+    /**
+     * This test triggers recursion by calling `System.getLogger` in the class init and constructor
+     * of a custom LoggerFinder. Without the fix, this is expected to throw
+     * java.lang.NoClassDefFoundError: Could not initialize class jdk.internal.logger.LoggerFinderLoader$ErrorPolicy
+     * caused by: java.lang.StackOverflowError
+     */
+    public static void main(String[] args) throws Throwable {
+        PlatformLogger.getLogger("main").info("in main");
+        // allow time to let bootstrap logger flush data
+        BootstrapLoggerUtils.awaitPending();
+        List logs = loggerfinder.SimpleLoggerFinder.LOGS;
+        logs.stream().map(SimpleLogRecord::of).forEach(System.out::println);
+        logs.stream().map(SimpleLogRecord::of).forEach(SimpleLogRecord::check);
+        assertEquals(String.valueOf(logs.size()), String.valueOf(3));
+    }
+
+    static List asList(Object[] params) {
+        return params == null ? null : Arrays.asList(params);
+    }
+
+    record SimpleLogRecord(String message, Instant instant, String loggerName,
+                           java.util.logging.Level level, List params,
+                           String resourceBundleName, long seqNumber,
+                           String sourceClassName, String methodName, Throwable thrown) {
+        SimpleLogRecord(LogRecord record) {
+            this(record.getMessage(), record.getInstant(), record.getLoggerName(), record.getLevel(),
+                    asList(record.getParameters()), record.getResourceBundleName(), record.getSequenceNumber(),
+                    record.getSourceClassName(), record.getSourceMethodName(), record.getThrown());
+        }
+        static SimpleLogRecord of(Object o) {
+            return (o instanceof LogRecord record) ? new SimpleLogRecord(record) : null;
+        }
+        static SimpleLogRecord check(SimpleLogRecord record) {
+            if (record.loggerName.equals("dummy")) {
+                assertEquals(record.sourceClassName, "jdk.internal.logger.BootstrapLogger$LogEvent");
+                assertEquals(record.methodName(), "log");
+            }
+            if (record.loggerName.equals("main")) {
+                assertEquals(record.sourceClassName, PlatformRecursiveLoadingTest.class.getName());
+                assertEquals(record.methodName, "main");
+            }
+            return record;
+        }
+    }
+
+    private static void assertEquals(String received, String expected) {
+        if (!expected.equals(received)) {
+            throw new RuntimeException("Received: " + received);
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/RecursiveLoadingTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/RecursiveLoadingTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/RecursiveLoadingTest.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/RecursiveLoadingTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
+ * @bug 8314263
+ * @summary Creating a logger while loading the Logger finder
+ *          triggers recursion and StackOverflowError
+ * @modules java.base/jdk.internal.logger:+open
+ * @library ../lib
+ * @compile RecursiveLoadingTest.java SimpleLoggerFinder.java
+ * @run main/othervm RecursiveLoadingTest
+ */
+
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.LogRecord;
+
+public class RecursiveLoadingTest {
+
+    /**
+     * This test triggers recursion by calling `System.getLogger` in the class init and constructor
+     * of a custom LoggerFinder. Without the fix, this is expected to throw
+     * java.lang.NoClassDefFoundError: Could not initialize class jdk.internal.logger.LoggerFinderLoader$ErrorPolicy
+     * caused by: java.lang.StackOverflowError
+     */
+    public static void main(String[] args) throws Throwable {
+        System.getLogger("main").log(System.Logger.Level.INFO, "in main");
+        // allow time to let bootstrap logger flush data
+        BootstrapLoggerUtils.awaitPending();
+        List logs = loggerfinder.SimpleLoggerFinder.LOGS;
+        logs.stream().map(SimpleLogRecord::of).forEach(System.out::println);
+        logs.stream().map(SimpleLogRecord::of).forEach(SimpleLogRecord::check);
+        assertEquals(String.valueOf(logs.size()), String.valueOf(3));
+    }
+
+    static List asList(Object[] params) {
+        return params == null ? null : Arrays.asList(params);
+    }
+
+    record SimpleLogRecord(String message, Instant instant, String loggerName,
+                           java.util.logging.Level level, List params,
+                           String resourceBundleName, long seqNumber,
+                           String sourceClassName, String methodName, Throwable thrown) {
+        SimpleLogRecord(LogRecord record) {
+            this(record.getMessage(), record.getInstant(), record.getLoggerName(), record.getLevel(),
+                    asList(record.getParameters()), record.getResourceBundleName(), record.getSequenceNumber(),
+                    record.getSourceClassName(), record.getSourceMethodName(), record.getThrown());
+        }
+        static SimpleLogRecord of(Object o) {
+            return (o instanceof LogRecord record) ? new SimpleLogRecord(record) : null;
+        }
+        static SimpleLogRecord check(SimpleLogRecord record) {
+            if (record.loggerName.equals("dummy")) {
+                assertEquals(record.sourceClassName, "jdk.internal.logger.BootstrapLogger$LogEvent");
+                assertEquals(record.methodName(), "log");
+            }
+            if (record.loggerName.equals("main")) {
+                assertEquals(record.sourceClassName, RecursiveLoadingTest.class.getName());
+                assertEquals(record.methodName, "main");
+            }
+            return record;
+        }
+    }
+
+    private static void assertEquals(String received, String expected) {
+        if (!expected.equals(received)) {
+            throw new RuntimeException("Received: " + received);
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,132 @@
+/*
+ * 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 loggerfinder;
+
+import java.lang.*;
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+public class SimpleLoggerFinder extends System.LoggerFinder {
+
+    public static final CopyOnWriteArrayList LOGS = new CopyOnWriteArrayList<>();
+    static {
+        try {
+            long sleep = new Random().nextLong(1000L) + 1L;
+            // simulate a slow load service
+            Thread.sleep(sleep);
+            System.getLogger("dummy")
+                    .log(System.Logger.Level.INFO,
+                            "Logger finder service load sleep value: " + sleep);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private final Map loggers = new ConcurrentHashMap<>();
+    public SimpleLoggerFinder() {
+        System.getLogger("dummy")
+                .log(System.Logger.Level.INFO,
+                        "Logger finder service created");
+    }
+
+    @Override
+    public System.Logger getLogger(String name, Module module) {
+        return loggers.computeIfAbsent(name, SimpleLogger::new);
+    }
+
+    private static class SimpleLogger implements System.Logger {
+        private final java.util.logging.Logger logger;
+
+        private static final class SimpleHandler extends Handler {
+            @Override
+            public void publish(LogRecord record) {
+                LOGS.add(record);
+            }
+            @Override public void flush() { }
+            @Override public void close() { }
+        }
+
+        public SimpleLogger(String name) {
+            logger = Logger.getLogger(name);
+            logger.addHandler(new SimpleHandler());
+        }
+
+        @Override
+        public String getName() {
+            return logger.getName();
+        }
+
+        java.util.logging.Level level(Level level) {
+            return switch (level) {
+                case ALL -> java.util.logging.Level.ALL;
+                case DEBUG -> java.util.logging.Level.FINE;
+                case TRACE -> java.util.logging.Level.FINER;
+                case INFO -> java.util.logging.Level.INFO;
+                case WARNING -> java.util.logging.Level.WARNING;
+                case ERROR -> java.util.logging.Level.SEVERE;
+                case OFF -> java.util.logging.Level.OFF;
+            };
+        }
+
+        @Override
+        public boolean isLoggable(Level level) {
+            return logger.isLoggable(level(level));
+        }
+
+        @Override
+        public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
+            var julLevel = level(level);
+            if (!logger.isLoggable(julLevel)) return;
+            if (bundle != null) {
+                logger.logrb(julLevel, bundle, msg, thrown);
+            } else {
+                logger.log(julLevel, msg, thrown);
+            }
+        }
+
+        @Override
+        public void log(Level level, ResourceBundle bundle, String format, Object... params) {
+            var julLevel = level(level);
+            if (!logger.isLoggable(julLevel)) return;
+            if (params == null) {
+                if (bundle == null) {
+                    logger.log(julLevel, format);
+                } else {
+                    logger.logrb(julLevel, bundle, format);
+                }
+            } else {
+                if (bundle == null) {
+                    logger.log(julLevel, format, params);
+                } else {
+                    logger.logrb(julLevel, bundle, format, params);
+                }
+            }
+        }
+    }
+}
+
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/META-INF/services/java.lang.System$LoggerFinder openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/META-INF/services/java.lang.System$LoggerFinder
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/META-INF/services/java.lang.System$LoggerFinder	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/META-INF/services/java.lang.System$LoggerFinder	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1 @@
+loggerfinder.SimpleLoggerFinder
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SignedLoggerFinderTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SignedLoggerFinderTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SignedLoggerFinderTest.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SignedLoggerFinderTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,307 @@
+/*
+ * 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 8314263
+ * @summary Signed jars triggering Logger finder recursion and StackOverflowError
+ * @library /test/lib ../lib
+ * @compile/module=java.base share/classes/jdk/internal/event/EventHelper.java
+ * @modules java.base/jdk.internal.logger:+open
+ * @build jdk.test.lib.compiler.CompilerUtils
+ *        jdk.test.lib.process.*
+ *        jdk.test.lib.util.JarUtils
+ *        jdk.test.lib.JDKToolLauncher
+ * @compile SignedLoggerFinderTest.java SimpleLoggerFinder.java
+ * @run main SignedLoggerFinderTest init
+ * @run main SignedLoggerFinderTest init sign
+ */
+
+import java.io.File;
+import java.nio.file.*;
+import java.security.*;
+import java.util.*;
+import java.util.function.*;
+import java.util.jar.*;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.util.JarUtils;
+
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+import static java.util.Arrays.asList;
+
+public class SignedLoggerFinderTest {
+
+    /**
+     * This test triggers recursion in the broken JDK. The error can
+     * manifest in a few different ways.
+     * One error seen is "java.lang.NoClassDefFoundError:
+     * Could not initialize class jdk.internal.logger.LoggerFinderLoader$ErrorPolicy"
+     *
+     * The original reported error was a StackOverflow (also seen in different iterations
+     * of this run). Running test in signed and unsigned jar mode for sanity coverage.
+     * The current bug only manifests when jars are signed.
+     */
+
+    private static boolean init = false;
+    private static boolean signJars = false;
+    private static boolean mutliThreadLoad = false;
+    private static volatile boolean testComplete = false;
+
+    private static final String KEYSTORE = "8314263.keystore";
+    private static final String ALIAS = "JavaTest";
+    private static final String STOREPASS = "changeit";
+    private static final String KEYPASS = "changeit";
+    private static final String DNAME = "CN=sample";
+    private static final String CUSTOM_LOGGER_FINDER_NAME =
+            "loggerfinder.SimpleLoggerFinder";
+    private static final String CUSTOM_LOGGER_NAME =
+            "loggerfinder.SimpleLoggerFinder$SimpleLogger";
+    private static final String INTERNAL_LOGGER_FINDER_NAME =
+            "sun.util.logging.internal.LoggingProviderImpl";
+    private static final String INTERNAL_LOGGER_NAME =
+            "sun.util.logging.internal.LoggingProviderImpl$JULWrapper";
+    private static final Path jarPath1 =
+        Path.of(System.getProperty("test.classes", "."), "SimpleLoggerFinder.jar");
+    private static final Path jarPath2 =
+            Path.of(System.getProperty("test.classes", "."), "SimpleLoggerFinder2.jar");
+
+    public static void main(String[] args) throws Throwable {
+        init = args.length >=1 && args[0].equals("init");
+        signJars = args.length >=2 && args[1].equals("sign");
+
+        // init only passed in by jtreg test run, initialize the environment
+        // for the subsequent test run
+        if (init) {
+            initialize();
+            launchTest(false, false);
+            launchTest(false, true);
+            launchTest(true, false);
+            launchTest(true, true);
+
+        } else {
+            // set up complete. Run the code to trigger the recursion
+            // We're in the JVM launched by ProcessTools.executeCommand
+            boolean multiThreadLoad = Boolean.getBoolean("multiThreadLoad");
+            boolean withCustomLoggerFinder = Boolean.getBoolean("withCustomLoggerFinder");
+
+            if (multiThreadLoad) {
+                long sleep = new Random().nextLong(100L) + 1L;
+                System.out.println("multi thread load sleep value: " + sleep);
+                new Thread(runnableWithSleep(
+                        () -> System.getLogger("logger" + System.currentTimeMillis()),
+                        sleep, "System.getLogger type: ")).start();
+                new Thread(runnableWithSleep(
+                        () -> System.LoggerFinder.getLoggerFinder(),
+                        sleep, "System.getLoggerFinder type: ")).start();
+            }
+
+            if (withCustomLoggerFinder) {
+                JarFile jf = new JarFile(jarPath1.toString(), true);
+                jf.getInputStream(jf.getJarEntry("loggerfinder/SimpleLoggerFinder.class"));
+                JarFile jf2 = new JarFile(jarPath2.toString(), true);
+                jf2.getInputStream(jf.getJarEntry("loggerfinder/SimpleLoggerFinder.class"));
+            } else {
+                // some other call to prod LoggerFinder loading
+                System.getLogger("random" + System.currentTimeMillis());
+                System.LoggerFinder.getLoggerFinder();
+            }
+            Security.setProperty("test_1", "test");
+
+            // some extra sanity checks
+            if (withCustomLoggerFinder) {
+                assertEquals(System.LoggerFinder.getLoggerFinder().getClass().getName(),
+                        CUSTOM_LOGGER_FINDER_NAME);
+                System.Logger testLogger = System.getLogger("jdk.event.security");
+                assertEquals(testLogger.getClass().getName(), CUSTOM_LOGGER_NAME);
+            } else {
+                assertEquals(System.LoggerFinder.getLoggerFinder().getClass().getName(),
+                        INTERNAL_LOGGER_FINDER_NAME);
+                System.Logger testLogger = System.getLogger("jdk.event.security");
+                assertEquals(testLogger.getClass().getName(), INTERNAL_LOGGER_NAME);
+            }
+            testComplete = true;
+
+            // LoggerFinder should be initialized, trigger a simple log call
+            Security.setProperty("test_2", "test");
+            // allow time to let bootstrap logger flush data
+            BootstrapLoggerUtils.awaitPending();
+        }
+    }
+
+    // helper to create the inner test. Run config variations with the LoggerFinder jars
+    // on the classpath and with other threads running System.Logger calls during load
+    private static void launchTest(boolean multiThreadLoad, boolean withCustomLoggerFinder) {
+        List cmds = new ArrayList<>();
+        cmds.add(JDKToolFinder.getJDKTool("java"));
+        cmds.addAll(asList(Utils.getTestJavaOpts()));
+        if (withCustomLoggerFinder) {
+            cmds.addAll(List.of("-classpath",
+                System.getProperty("test.classes") + File.pathSeparator +
+                jarPath1.toString() + File.pathSeparator + jarPath2.toString(),
+                "-Dtest.classes=" + System.getProperty("test.classes")));
+        } else {
+            cmds.addAll(List.of("-classpath",
+                System.getProperty("test.classes")));
+        }
+
+        Path patches = Paths.get(System.getProperty("test.classes"), "patches", "java.base");
+        cmds.addAll(List.of(
+            // patch of EventHelper to log at INFO level (for bootstrap logger)
+            "--patch-module", "java.base=" + patches.toString(),
+            // allow test to access internal bootstrap logger functionality
+            "--add-opens=java.base/jdk.internal.logger=ALL-UNNAMED",
+            // following debug property seems useful to tickle the issue
+            "-Dsun.misc.URLClassPath.debug=true",
+            // console logger level to capture event output
+            "-Djdk.system.logger.level=DEBUG",
+            // useful for debug purposes
+            "-Djdk.logger.finder.error=DEBUG",
+            // enable logging to verify correct output
+            "-Djava.util.logging.config.file=" +
+                    Path.of(System.getProperty("test.src", "."), "logging.properties")));
+        if (multiThreadLoad) {
+            cmds.add("-DmultiThreadLoad=true");
+        }
+        if (withCustomLoggerFinder) {
+            cmds.add("-DwithCustomLoggerFinder=true");
+        }
+        cmds.addAll(List.of(
+            "SignedLoggerFinderTest",
+            "no-init"));
+
+        try {
+            OutputAnalyzer outputAnalyzer = ProcessTools.executeCommand(cmds.stream()
+                    .filter(t -> !t.isEmpty())
+                    .toArray(String[]::new))
+                    .shouldHaveExitValue(0);
+            if (withCustomLoggerFinder) {
+                outputAnalyzer
+                    .shouldContain("TEST LOGGER: [test_1, test]")
+                    .shouldContain("TEST LOGGER: [test_2, test]");
+            } else {
+                outputAnalyzer
+                    .shouldContain("SecurityPropertyModification: key:test_1")
+                    .shouldContain("SecurityPropertyModification: key:test_2");
+            }
+            if (withCustomLoggerFinder && signJars) {
+                // X509 cert generated during verification of signed jar file
+                outputAnalyzer
+                    .shouldContain(DNAME);
+            }
+
+        } catch (Throwable t) {
+            throw new RuntimeException("Unexpected fail.", t);
+        }
+    }
+
+    private static Runnable runnableWithSleep(Supplier s, long sleep, String desc) {
+        return () -> {
+            while(!testComplete) {
+                System.out.println(desc + s.get().getClass().getName());
+                try {
+                    Thread.sleep(sleep);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        };
+    }
+
+    private static void initialize() throws Throwable {
+        if (signJars) {
+            genKey();
+        }
+
+        Path classes = Paths.get(System.getProperty("test.classes", ""));
+        JarUtils.createJarFile(jarPath1,
+            classes,
+            classes.resolve("loggerfinder/SimpleLoggerFinder.class"),
+            classes.resolve("loggerfinder/SimpleLoggerFinder$SimpleLogger.class"));
+
+        JarUtils.updateJarFile(jarPath1, Path.of(System.getProperty("test.src")),
+            Path.of("META-INF", "services", "java.lang.System$LoggerFinder"));
+        if (signJars) {
+            signJar(jarPath1.toString());
+        }
+        // multiple signed jars with services to have ServiceLoader iteration
+        Files.copy(jarPath1, jarPath2, REPLACE_EXISTING);
+    }
+
+    private static void genKey() throws Throwable {
+        String keytool = JDKToolFinder.getJDKTool("keytool");
+        Files.deleteIfExists(Paths.get(KEYSTORE));
+        ProcessTools.executeCommand(keytool,
+                "-J-Duser.language=en",
+                "-J-Duser.country=US",
+                "-genkey",
+                "-keyalg", "rsa",
+                "-alias", ALIAS,
+                "-keystore", KEYSTORE,
+                "-keypass", KEYPASS,
+                "-dname", DNAME,
+                "-storepass", STOREPASS
+        ).shouldHaveExitValue(0);
+    }
+
+
+    private static OutputAnalyzer signJar(String jarName) throws Throwable {
+        List args = new ArrayList<>();
+        args.add("-verbose");
+        args.add(jarName);
+        args.add(ALIAS);
+
+        return jarsigner(args);
+    }
+
+    private static OutputAnalyzer jarsigner(List extra)
+            throws Throwable {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jarsigner")
+                .addVMArg("-Duser.language=en")
+                .addVMArg("-Duser.country=US")
+                .addToolArg("-keystore")
+                .addToolArg(KEYSTORE)
+                .addToolArg("-storepass")
+                .addToolArg(STOREPASS)
+                .addToolArg("-keypass")
+                .addToolArg(KEYPASS);
+        for (String s : extra) {
+            if (s.startsWith("-J")) {
+                launcher.addVMArg(s.substring(2));
+            } else {
+                launcher.addToolArg(s);
+            }
+        }
+        return ProcessTools.executeCommand(launcher.getCommand());
+    }
+
+    private static void assertEquals(String received, String expected) {
+        if (!expected.equals(received)) {
+            throw new RuntimeException("Received: " + received);
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SimpleLoggerFinder.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SimpleLoggerFinder.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SimpleLoggerFinder.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SimpleLoggerFinder.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,74 @@
+/*
+ * 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 loggerfinder;
+
+import java.lang.*;
+import java.util.*;
+
+public class SimpleLoggerFinder extends System.LoggerFinder {
+
+    static {
+        try {
+            long sleep = new Random().nextLong(1000L) + 1L;
+            System.out.println("Logger finder service load sleep value: " + sleep);
+            // simulate a slow load service
+            Thread.sleep(sleep);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+     @Override
+     public System.Logger getLogger(String name, Module module) {
+         return new SimpleLogger(name);
+     }
+
+    private static class SimpleLogger implements System.Logger {
+        private final String name;
+
+        public SimpleLogger(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public boolean isLoggable(Level level) {
+            return true;
+        }
+
+        @Override
+        public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
+            System.out.println("TEST LOGGER: " + msg);
+        }
+
+        @Override
+        public void log(Level level, ResourceBundle bundle, String format, Object... params) {
+            System.out.println("TEST LOGGER: " + Arrays.asList(params));
+
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/java.base/share/classes/jdk/internal/event/EventHelper.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/java.base/share/classes/jdk/internal/event/EventHelper.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/java.base/share/classes/jdk/internal/event/EventHelper.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/java.base/share/classes/jdk/internal/event/EventHelper.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,155 @@
+/*
+ * 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.event;
+
+import jdk.internal.access.JavaUtilJarAccess;
+import jdk.internal.access.SharedSecrets;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * A helper class to have events logged to a JDK Event Logger.
+ */
+
+public final class EventHelper {
+
+    private static final JavaUtilJarAccess JUJA = SharedSecrets.javaUtilJarAccess();
+    private static volatile boolean loggingSecurity;
+    private static volatile System.Logger securityLogger;
+    private static final VarHandle LOGGER_HANDLE;
+    static {
+        System.err.println("Patch version of EventHelper loaded");
+        try {
+            LOGGER_HANDLE =
+                    MethodHandles.lookup().findStaticVarHandle(
+                            EventHelper.class, "securityLogger", System.Logger.class);
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+    // a patch module to help this test ensure events are logged when
+    // bootstrap logger is in use
+    private static final System.Logger.Level LOG_LEVEL = System.Logger.Level.INFO;
+
+    // helper class used for logging security related events for now
+    private static final String SECURITY_LOGGER_NAME = "jdk.event.security";
+
+
+    public static void logTLSHandshakeEvent(Instant start,
+                                            String peerHost,
+                                            int peerPort,
+                                            String cipherSuite,
+                                            String protocolVersion,
+                                            long peerCertId) {
+        assert securityLogger != null;
+        String prepend = getDurationString(start);
+        securityLogger.log(LOG_LEVEL, prepend +
+        " TLSHandshake: {0}:{1,number,#}, {2}, {3}, {4,number,#}",
+        peerHost, peerPort, protocolVersion, cipherSuite, peerCertId);
+    }
+
+    public static void logSecurityPropertyEvent(String key,
+                                                String value) {
+
+        assert securityLogger != null;
+        securityLogger.log(LOG_LEVEL,
+            "SecurityPropertyModification: key:{0}, value:{1}", key, value);
+    }
+
+    public static void logX509ValidationEvent(long anchorCertId,
+                                         long[] certIds) {
+        assert securityLogger != null;
+        String codes = LongStream.of(certIds)
+                .mapToObj(Long::toString)
+                .collect(Collectors.joining(", "));
+        securityLogger.log(LOG_LEVEL,
+                "ValidationChain: {0,number,#}, {1}", anchorCertId, codes);
+    }
+
+    public static void logX509CertificateEvent(String algId,
+                                               String serialNum,
+                                               String subject,
+                                               String issuer,
+                                               String keyType,
+                                               int length,
+                                               long certId,
+                                               long beginDate,
+                                               long endDate) {
+        assert securityLogger != null;
+        securityLogger.log(LOG_LEVEL, "X509Certificate: Alg:{0}, Serial:{1}" +
+            ", Subject:{2}, Issuer:{3}, Key type:{4}, Length:{5,number,#}" +
+            ", Cert Id:{6,number,#}, Valid from:{7}, Valid until:{8}",
+            algId, serialNum, subject, issuer, keyType, length,
+            certId, new Date(beginDate), new Date(endDate));
+    }
+
+    /**
+     * Method to calculate a duration timestamp for events which measure
+     * the start and end times of certain operations.
+     * @param start Instant indicating when event started recording
+     * @return A string representing duraction from start time to
+     * time of this method call. Empty string is start is null.
+     */
+    private static String getDurationString(Instant start) {
+        if (start != null) {
+            if (start.equals(Instant.MIN)) {
+                return "N/A";
+            }
+            Duration duration = Duration.between(start, Instant.now());
+            long micros = duration.toNanos() / 1_000;
+            if (micros < 1_000_000) {
+                return "duration = " + (micros / 1_000.0) + " ms:";
+            } else {
+                return "duration = " + ((micros / 1_000) / 1_000.0) + " s:";
+            }
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * Helper to determine if security events are being logged
+     * at a preconfigured logging level. The configuration value
+     * is read once at class initialization.
+     *
+     * @return boolean indicating whether an event should be logged
+     */
+    public static boolean isLoggingSecurity() {
+        // Avoid a bootstrap issue where the commitEvent attempts to
+        // trigger early loading of System Logger but where
+        // the verification process still has JarFiles locked
+        if (securityLogger == null && !JUJA.isInitializing()) {
+            LOGGER_HANDLE.compareAndSet( null, System.getLogger(SECURITY_LOGGER_NAME));
+            loggingSecurity = securityLogger.isLoggable(LOG_LEVEL);
+        }
+        return loggingSecurity;
+    }
+
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/logging.properties openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/logging.properties
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/logging.properties	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/logging.properties	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,14 @@
+############################################################
+#  	Configuration file for log testing
+#
+############################################################
+
+handlers= java.util.logging.ConsoleHandler
+
+.level= FINE
+
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+jdk.event.security.level = FINE
+
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -29,7 +29,7 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.ResourceBundle;
-import java.util.Set;
+
 import jdk.internal.logger.BootstrapLogger;
 import jdk.internal.logger.LazyLoggers;
 
@@ -38,9 +38,10 @@
  * @bug     8144460 8144214
  * @summary Cover the logXX and LogEvent.valueOf APIs of BootstrapLogger
  *          and logXX APIs of SimpleConsoleLogger.
+ * @library ../../lib
  * @modules java.base/jdk.internal.logger:+open
  *          java.base/sun.util.logging
- * @build BootstrapLoggerUtils LogStream
+ * @build LogStream
  * @run main/othervm BootstrapLoggerAPIsTest
  */
 
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, 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
@@ -53,9 +53,10 @@
  * @summary JDK implementation specific unit test for JDK internal artifacts.
             Tests the behavior of bootstrap loggers (and SimpleConsoleLoggers
  *          too).
+ * @library ../../lib
  * @modules java.base/jdk.internal.logger:+open
  *          java.logging
- * @build BootstrapLoggerUtils LogStream
+ * @build LogStream
  * @run main/othervm BootstrapLoggerTest NO_SECURITY
  * @run main/othervm -Djava.security.manager=allow BootstrapLoggerTest SECURE
  * @run main/othervm/timeout=120 -Djava.security.manager=allow BootstrapLoggerTest SECURE_AND_WAIT
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerUtils.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerUtils.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerUtils.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerUtils.java	1970-01-01 00:00:00.000000000 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.function.BooleanSupplier;
-
-import jdk.internal.logger.BootstrapLogger;
-
-class BootstrapLoggerUtils {
-
-    private static final Field IS_BOOTED;
-    private static final Method AWAIT_PENDING;
-
-    static {
-        try {
-            IS_BOOTED = BootstrapLogger.class.getDeclaredField("isBooted");
-            IS_BOOTED.setAccessible(true);
-            // private reflection hook that allows us to test wait until all
-            // the tasks pending in the BootstrapExecutor are finished.
-            AWAIT_PENDING = BootstrapLogger.class.getDeclaredMethod("awaitPendingTasks");
-            AWAIT_PENDING.setAccessible(true);
-        } catch (Exception ex) {
-            throw new ExceptionInInitializerError(ex);
-        }
-    }
-
-    static void setBootedHook(BooleanSupplier supplier) throws IllegalAccessException {
-        IS_BOOTED.set(null, supplier);
-    }
-
-    static void awaitPending() {
-        try {
-            AWAIT_PENDING.invoke(null);
-        } catch (IllegalAccessException | IllegalArgumentException
-                | InvocationTargetException ex) {
-            ex.printStackTrace();
-        }
-    }
-}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/LogStream.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/LogStream.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/LogStream.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/LogStream.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -25,8 +25,6 @@
 import java.io.OutputStream;
 import java.io.PrintStream;
 
-import jdk.internal.logger.BootstrapLogger;
-
 /**
  * We use an instance of this class to check what the logging system has printed
  * on System.err.
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/lib/BootstrapLoggerUtils.java openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/lib/BootstrapLoggerUtils.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/System/LoggerFinder/lib/BootstrapLoggerUtils.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/System/LoggerFinder/lib/BootstrapLoggerUtils.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,61 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.function.BooleanSupplier;
+
+import jdk.internal.logger.BootstrapLogger;
+
+public final class BootstrapLoggerUtils {
+
+    private static final Field IS_BOOTED;
+    private static final Method AWAIT_PENDING;
+
+    static {
+        try {
+            IS_BOOTED = BootstrapLogger.class.getDeclaredField("isBooted");
+            IS_BOOTED.setAccessible(true);
+            // private reflection hook that allows us to test wait until all
+            // the tasks pending in the BootstrapExecutor are finished.
+            AWAIT_PENDING = BootstrapLogger.class.getDeclaredMethod("awaitPendingTasks");
+            AWAIT_PENDING.setAccessible(true);
+        } catch (Exception ex) {
+            throw new ExceptionInInitializerError(ex);
+        }
+    }
+
+    public static void setBootedHook(BooleanSupplier supplier) throws IllegalAccessException {
+        IS_BOOTED.set(null, supplier);
+    }
+
+    public static void awaitPending() {
+        try {
+            AWAIT_PENDING.invoke(null);
+        } catch (IllegalAccessException | IllegalArgumentException
+                | InvocationTargetException ex) {
+            ex.printStackTrace();
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/Thread/IsAlive.java openjdk-21-21.0.2+13/test/jdk/java/lang/Thread/IsAlive.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/Thread/IsAlive.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/Thread/IsAlive.java	2024-01-16 16:19:00.000000000 +0000
@@ -25,7 +25,7 @@
  * @test
  * @bug     8305425
  * @summary Check Thread.isAlive
- * @run main/othervm/timeout=10 IsAlive
+ * @run main/othervm IsAlive
  */
 
 public class IsAlive {
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java openjdk-21-21.0.2+13/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java	2024-01-16 16:19:00.000000000 +0000
@@ -34,7 +34,7 @@
  * @test
  * @requires vm.continuations & vm.debug
  * @modules java.base/java.lang:+open
- * @run junit/othervm -XX:+UseHeavyMonitors CarrierThreadWaits
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:LockingMode=0 CarrierThreadWaits
  */
 
 import java.lang.management.LockInfo;
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java openjdk-21-21.0.2+13/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, 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
@@ -22,13 +22,13 @@
  */
 
 /* @test
- * @bug 4227192 8004928 8072656
+ * @bug 4227192 8004928 8072656 8319436
  * @summary This is a test of the restrictions on the parameters that may
  * be passed to the Proxy.getProxyClass method.
  * @author Peter Jones
  *
  * @build ClassRestrictions
- * @run main ClassRestrictions
+ * @run junit ClassRestrictions
  */
 
 import java.io.File;
@@ -37,6 +37,13 @@
 import java.net.URLClassLoader;
 import java.net.URL;
 import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import static org.junit.jupiter.api.Assertions.*;
 
 public class ClassRestrictions {
 
@@ -52,129 +59,65 @@
         void foo();
     }
 
-    public static final String nonPublicIntrfaceName = "java.util.zip.ZipConstants";
+    private static final String TEST_CLASSES = System.getProperty("test.classes", ".");
+    private static final ClassLoader LOADER = ClassRestrictions.class.getClassLoader();
+
+    static Stream>> badProxyInterfaces() {
+        return Stream.of(
+                List.of(Object.class),          // proxy interface cannot be a class
+                List.of(int.class),             // proxy interface can't be primitive type
+                List.of(Bar.class, Bar.class),  // cannot have repeated interfaces
+                // two proxy interfaces have the method of same method name but different return type
+                List.of(Bar.class, Baz.class)
+        );
+    }
+
+    /*
+     * Test cases for illegal proxy interfaces
+     */
+    @ParameterizedTest
+    @MethodSource("badProxyInterfaces")
+    void testForName(List> interfaces) {
+        assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(LOADER, interfaces.toArray(Class[]::new)));
+    }
+
+    private static final String nonPublicIntrfaceName = "java.util.zip.ZipConstants";
 
-    public static void main(String[] args) {
+    /*
+     * All non-public interfaces must be in the same package.
+     */
+    @Test
+    void testNonPublicIntfs() throws Exception {
+        var nonPublic1 = Bashful.class;
+        var nonPublic2 = Class.forName(nonPublicIntrfaceName);
+        assertFalse(Modifier.isPublic(nonPublic2.getModifiers()),
+            "Interface " + nonPublicIntrfaceName + " is public and need to be changed!");
+        var interfaces = new Class[] { nonPublic1, nonPublic2 };
+        assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(LOADER, interfaces));
+    }
 
-        System.err.println(
-            "\nTest of restrictions on parameters to Proxy.getProxyClass\n");
+    static Stream loaders() {
+        return Stream.of(null,
+                         ClassLoader.getPlatformClassLoader(),
+                         ClassLoader.getSystemClassLoader(),
+                         LOADER);
+    }
 
-        try {
-            ClassLoader loader = ClassRestrictions.class.getClassLoader();
-            Class[] interfaces;
-            Class proxyClass;
-
-            /*
-             * All of the Class objects in the interfaces array must represent
-             * interfaces, not classes or primitive types.
-             */
-            try {
-                interfaces = new Class[] { Object.class };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with java.lang.Object as interface");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-            try {
-                interfaces = new Class[] { Integer.TYPE };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with int.class as interface");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * No two elements in the interfaces array may refer to identical
-             * Class objects.
-             */
-            try {
-                interfaces = new Class[] { Bar.class, Bar.class };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with repeated interfaces");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * All of the interfaces types must be visible by name though the
-             * specified class loader.
-             */
-            String[] cpaths = System.getProperty("test.classes", ".")
-                                    .split(File.pathSeparator);
-            URL[] urls = new URL[cpaths.length];
-            for (int i=0; i < cpaths.length; i++) {
-                urls[i] = Paths.get(cpaths[i]).toUri().toURL();
-            }
-            ClassLoader altLoader = new URLClassLoader(urls, null);
-            Class altBarClass;
-            altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
-            try {
-                interfaces = new Class[] { altBarClass };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with interface " +
-                    "not visible to class loader");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * All non-public interfaces must be in the same package.
-             */
-            Class nonPublic1 = Bashful.class;
-            Class nonPublic2 = Class.forName(nonPublicIntrfaceName);
-            if (Modifier.isPublic(nonPublic2.getModifiers())) {
-                throw new Error(
-                    "Interface " + nonPublicIntrfaceName +
-                    " is public and need to be changed!");
-            }
-            try {
-                interfaces = new Class[] { nonPublic1, nonPublic2 };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with two non-public interfaces " +
-                    "in different packages");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * No two interfaces may each have a method with the same name and
-             * parameter signature but different return type.
-             */
-            try {
-                interfaces = new Class[] { Bar.class, Baz.class };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with conflicting methods");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * All components of this test have passed.
-             */
-            System.err.println("\nTEST PASSED");
-
-        } catch (Throwable e) {
-            System.err.println("\nTEST FAILED:");
-            e.printStackTrace();
-            throw new Error("TEST FAILED: ", e);
+    /*
+     * All of the interfaces types must be visible by name though the
+     * specified class loader.
+     */
+    @ParameterizedTest
+    @MethodSource("loaders")
+    void testNonVisibleInterface(ClassLoader loader) throws Exception {
+        String[] cpaths = TEST_CLASSES.split(File.pathSeparator);
+        URL[] urls = new URL[cpaths.length];
+        for (int i = 0; i < cpaths.length; i++) {
+            urls[i] = Paths.get(cpaths[i]).toUri().toURL();
         }
+        var altLoader = new URLClassLoader(urls, null);
+        var altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
+        var interfaces = new Class[]{ altBarClass };
+        assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(loader, interfaces));
     }
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java openjdk-21-21.0.2+13/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -42,6 +42,7 @@
 
 /**
  * @test
+ * @bug 8318144
  * @enablePreview
  * @compile SwitchBootstrapsTest.java
  * @run testng/othervm SwitchBootstrapsTest
@@ -72,7 +73,11 @@
     }
 
     private void testEnum(Enum target, int start, int result, Object... labels) throws Throwable {
-        MethodType switchType = MethodType.methodType(int.class, target.getClass(), int.class);
+        testEnum(target.getClass(), target, start, result, labels);
+    }
+
+    private void testEnum(Class targetClass, Enum target, int start, int result, Object... labels) throws Throwable {
+        MethodType switchType = MethodType.methodType(int.class, targetClass, int.class);
         MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker();
         assertEquals((int) indy.invoke(target, start), result);
         assertEquals(-1, (int) indy.invoke(null, start));
@@ -140,6 +145,31 @@
         testEnum(E1.A, 0, 0);
     }
 
+    public void testEnumsWithConstants() throws Throwable {
+        enum E {
+            A {},
+            B {},
+            C {}
+        }
+        ClassDesc eDesc = E.class.describeConstable().get();
+        Object[] typeParams = new Object[] {
+            EnumDesc.of(eDesc, "A"),
+            EnumDesc.of(eDesc, "B"),
+            EnumDesc.of(eDesc, "C"),
+            "a",
+            String.class
+        };
+        testType(E.A, 0, 0, typeParams);
+        testType(E.B, 0, 1, typeParams);
+        testType(E.C, 0, 2, typeParams);
+        testType("a", 0, 3, typeParams);
+        testType("x", 0, 4, typeParams);
+        testType('a', 0, 5, typeParams);
+        testEnum(E.class, E.A, 0, 0, "A", "B", "C");
+        testEnum(E.class, E.B, 0, 1, "A", "B", "C");
+        testEnum(E.class, E.C, 0, 2, "A", "B", "C");
+    }
+
     public void testWrongSwitchTypes() throws Throwable {
         MethodType[] switchTypes = new MethodType[] {
             MethodType.methodType(int.class, Object.class),
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/net/DatagramSocket/SendPortZero.java openjdk-21-21.0.2+13/test/jdk/java/net/DatagramSocket/SendPortZero.java
--- openjdk-21-21.0.1+12/test/jdk/java/net/DatagramSocket/SendPortZero.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/net/DatagramSocket/SendPortZero.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2021, 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
@@ -29,6 +29,7 @@
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
+import java.net.InetSocketAddress;
 import java.net.InetAddress;
 import java.net.MulticastSocket;
 import java.net.SocketException;
@@ -69,7 +70,7 @@
 
         // Addresses
         loopbackAddr = InetAddress.getLoopbackAddress();
-        //wildcardAddr = new InetSocketAddress(0).getAddress();
+        wildcardAddr = new InetSocketAddress(0).getAddress();
 
         // Packets
         // loopback w/port 0
@@ -77,29 +78,30 @@
         loopbackZeroPkt.setAddress(loopbackAddr);
         loopbackZeroPkt.setPort(0);
 
-        /*
-        //Commented until JDK-8236852 is fixed
-
         // wildcard w/port 0
         wildcardZeroPkt = new DatagramPacket(buf, 0, buf.length);
         wildcardZeroPkt.setAddress(wildcardAddr);
         wildcardZeroPkt.setPort(0);
 
-        //Commented until JDK-8236807 is fixed
-
         // wildcard addr w/valid port
+        // Not currently tested. See JDK-8236807
         wildcardValidPkt = new DatagramPacket(buf, 0, buf.length);
-        var addr = socket.getAddress();
-        wildcardValidPkt.setAddress(addr);
-        wildcardValidPkt.setPort(socket.getLocalPort());
-      */
+        wildcardValidPkt.setAddress(wildcardAddr);
+        wildcardValidPkt.setPort(datagramSocket.getLocalPort());
     }
 
     @DataProvider(name = "data")
     public Object[][] variants() {
         return new Object[][]{
                 { datagramSocket,        loopbackZeroPkt },
+                { datagramSocket,        wildcardZeroPkt },
+                // Re-enable when JDK-8236807 fixed
+                //{ datagramSocket,        wildcardValidPkt },
+
                 { datagramSocketAdaptor, loopbackZeroPkt },
+                { datagramSocketAdaptor, wildcardZeroPkt },
+                // Re-enable when JDK-8236807 fixed
+                //{ datagramSocketAdaptor, wildcardValidPkt },
         };
     }
 
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/net/DatagramSocket/TimeoutWithSM.java openjdk-21-21.0.2+13/test/jdk/java/net/DatagramSocket/TimeoutWithSM.java
--- openjdk-21-21.0.1+12/test/jdk/java/net/DatagramSocket/TimeoutWithSM.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/net/DatagramSocket/TimeoutWithSM.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,118 @@
+/*
+ * 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 Test a timed DatagramSocket.receive with a SecurityManager set
+ * @run main/othervm -Djava.security.manager=allow TimeoutWithSM
+ */
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketTimeoutException;
+import java.security.Permission;
+import java.time.Duration;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class TimeoutWithSM {
+
+    private static final int TIMEOUT = 10_000;
+
+    public static void main(String[] args) throws Exception {
+        try (var socket = new DatagramSocket(null)) {
+            InetAddress lb = InetAddress.getLoopbackAddress();
+            socket.bind(new InetSocketAddress(lb, 0));
+
+            // start sender to send datagrams to us
+            var done = new AtomicBoolean();
+            startSender(socket.getLocalSocketAddress(), done);
+
+            // set a SecurityManager that blocks datagrams from sender
+            System.setSecurityManager(new SecurityManager() {
+                @Override
+                public void checkPermission(Permission p) {
+                }
+                @Override
+                public void checkAccept(String host, int port) {
+                    var isa = new InetSocketAddress(host, port);
+                    System.out.println("checkAccept " + isa);
+                    throw new SecurityException();
+                }
+            });
+
+            // timed receive, should throw SocketTimeoutException
+            try {
+                socket.setSoTimeout(TIMEOUT);
+                try {
+                    byte[] bytes = new byte[1024];
+                    DatagramPacket p = new DatagramPacket(bytes, bytes.length);
+                    socket.receive(p);
+                    throw new RuntimeException("Packet received, unexpected!!! "
+                            + " sender=" + p.getSocketAddress() + ", len=" + p.getLength());
+                } catch (SocketTimeoutException expected) {
+                    System.out.println(expected + ", expected!!!");
+                }
+            } finally {
+                done.set(true);
+            }
+        }
+    }
+
+    /**
+     * Start a thread to send datagrams to the given target address at intervals of
+     * one second. The sender stops when done is set to true.
+     */
+    static void startSender(SocketAddress target, AtomicBoolean done) throws Exception {
+        assert target instanceof InetSocketAddress isa && isa.getAddress().isLoopbackAddress();
+        var sender = new DatagramSocket(null);
+        boolean started = false;
+        try {
+            InetAddress lb = InetAddress.getLoopbackAddress();
+            sender.bind(new InetSocketAddress(lb, 0));
+            Thread.ofPlatform().start(() -> {
+                try {
+                    try (sender) {
+                        byte[] bytes = "hello".getBytes("UTF-8");
+                        DatagramPacket p = new DatagramPacket(bytes, bytes.length);
+                        p.setSocketAddress(target);
+                        while (!done.get()) {
+                            System.out.println("Send datagram to " + target + " ...");
+                            sender.send(p);
+                            Thread.sleep(Duration.ofSeconds(1));
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            });
+            started = true;
+        } finally {
+            if (!started) {
+                sender.close();
+            }
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/net/MulticastSocket/SendPortZero.java openjdk-21-21.0.2+13/test/jdk/java/net/MulticastSocket/SendPortZero.java
--- openjdk-21-21.0.1+12/test/jdk/java/net/MulticastSocket/SendPortZero.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/net/MulticastSocket/SendPortZero.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2021, 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,7 @@
 import java.net.DatagramPacket;
 import java.net.MulticastSocket;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.MulticastSocket;
 import java.net.SocketException;
 import java.net.SocketPermission;
@@ -68,7 +69,7 @@
 
         // Addresses
         loopbackAddr = InetAddress.getLoopbackAddress();
-        //wildcardAddr = new InetSocketAddress(0).getAddress();
+        wildcardAddr = new InetSocketAddress(0).getAddress();
 
         // Packets
         // loopback w/port 0
@@ -76,28 +77,25 @@
         loopbackZeroPkt.setAddress(loopbackAddr);
         loopbackZeroPkt.setPort(0);
 
-        /*
-        //Commented until JDK-8236852 is fixed
-
         // wildcard w/port 0
         wildcardZeroPkt = new DatagramPacket(buf, 0, buf.length);
         wildcardZeroPkt.setAddress(wildcardAddr);
         wildcardZeroPkt.setPort(0);
 
-        //Commented until JDK-8236807 is fixed
-
         // wildcard addr w/valid port
+        // Not currently tested. See JDK-8236807
         wildcardValidPkt = new DatagramPacket(buf, 0, buf.length);
-        var addr = socket.getAddress();
-        wildcardValidPkt.setAddress(addr);
-        wildcardValidPkt.setPort(socket.getLocalPort());
-      */
+        wildcardValidPkt.setAddress(wildcardAddr);
+        wildcardValidPkt.setPort(multicastSocket.getLocalPort());
     }
 
     @DataProvider(name = "data")
     public Object[][] variants() {
         return new Object[][]{
-                { multicastSocket,       loopbackZeroPkt }
+                { multicastSocket,       loopbackZeroPkt },
+                { multicastSocket,       wildcardZeroPkt },
+                // Not currently tested. See JDK-8236807
+                //{ multicastSocket,       wildcardValidPkt }
         };
     }
 
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java openjdk-21-21.0.2+13/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -54,7 +54,7 @@
  * @test
  * @summary Tests HttpClient usage when configured with a local address to bind
  *          to, when sending requests
- * @bug 8209137
+ * @bug 8209137 8316031
  * @library /test/lib /test/jdk/java/net/httpclient/lib
  *
  * @build jdk.test.lib.net.SimpleSSLContext jdk.test.lib.net.IPSupport
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/net/httpclient/http2/IdlePooledConnectionTest.java openjdk-21-21.0.2+13/test/jdk/java/net/httpclient/http2/IdlePooledConnectionTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/net/httpclient/http2/IdlePooledConnectionTest.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/net/httpclient/http2/IdlePooledConnectionTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,178 @@
+/*
+ * 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.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandlers;
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import jdk.httpclient.test.lib.common.HttpServerAdapters;
+import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange;
+import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer;
+import jdk.internal.net.http.common.Utils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import static java.net.http.HttpClient.Builder.NO_PROXY;
+import static java.net.http.HttpClient.Version.HTTP_2;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+
+/*
+ * @test
+ * @bug 8312433
+ * @summary verify that the HttpClient's HTTP2 idle connection management doesn't close a connection
+ *          when that connection has been handed out from the pool to a caller
+ * @library /test/jdk/java/net/httpclient/lib
+ * @build jdk.httpclient.test.lib.common.HttpServerAdapters
+ *
+ * @run junit/othervm   -Djdk.internal.httpclient.debug=true
+ *                      -Djdk.httpclient.keepalive.timeout.h2=3
+ *                      IdlePooledConnectionTest
+ */
+public class IdlePooledConnectionTest {
+
+    private static final String ALL_OK_PATH = "/allOK";
+    private static HttpTestServer h2Server;
+    private static URI allOKUri;
+    private static final String H2_KEEPALIVE_TIMEOUT_PROP = "jdk.httpclient.keepalive.timeout.h2";
+    private static final String KEEPALIVE_TIMEOUT_PROP = "jdk.httpclient.keepalive.timeout";
+
+    @BeforeAll
+    static void beforeAll() throws Exception {
+        h2Server = HttpTestServer.create(HTTP_2);
+        h2Server.addHandler(new AllOKHandler(), ALL_OK_PATH);
+        h2Server.start();
+        System.err.println("Started H2 server at " + h2Server.serverAuthority());
+        allOKUri = new URI("http://" + h2Server.serverAuthority() + ALL_OK_PATH);
+    }
+
+    @AfterAll
+    static void afterAll() throws Exception {
+        if (h2Server != null) {
+            System.err.println("Stopping h2 server: " + h2Server.serverAuthority());
+            h2Server.stop();
+        }
+    }
+
+    // just returns a 200 HTTP response for all requests
+    private static final class AllOKHandler implements HttpServerAdapters.HttpTestHandler {
+
+        @Override
+        public void handle(final HttpTestExchange exchange) throws IOException {
+            System.err.println("Responding with 200 response code for request "
+                    + exchange.getRequestURI());
+            exchange.sendResponseHeaders(200, 0);
+        }
+    }
+
+    /*
+     * Issues a HTTP2 request against a server and expects it to succeed.
+     * The connection that was used is internally pooled by the HttpClient implementation.
+     * Then waits for the H2 idle connection timeout, before again firing several concurrent HTTP2
+     * requests against the same server. It is expected that all these requests complete
+     * successfully without running into a race condition where the H2 idle connection management
+     * closes the (pooled) connection during the time connection has been handed out to a caller
+     * and a new stream hasn't yet been created.
+     */
+    @Test
+    public void testPooledConnection() throws Exception {
+        final Duration h2TimeoutDuration = getEffectiveH2IdleTimeoutDuration();
+        assertNotNull(h2TimeoutDuration, "H2 idle connection timeout cannot be null");
+        // the wait time, which represents the time to wait before firing off additional requests,
+        // is intentionally a few milliseconds smaller than the h2 idle connection timeout,
+        // to allow for the requests to reach the place where connection checkout from the pool
+        // happens and thus allow the code to race with the idle connection timer task
+        // closing the connection.
+        final long waitTimeMillis = TimeUnit.of(ChronoUnit.MILLIS).convert(h2TimeoutDuration) - 5;
+        try (final HttpClient client = HttpClient.newBuilder().proxy(NO_PROXY).build()) {
+            final HttpRequest request = HttpRequest.newBuilder(allOKUri)
+                    .GET().version(HTTP_2).build();
+            // keep ready the additional concurrent requests that we will fire later.
+            // we do this now so that when it's time to fire off these additional requests,
+            // this main thread does as little work as possible to increase the chances of a
+            // race condition in idle connection management closing a pooled connection
+            // and new requests being fired
+            final Callable> task = () -> client.send(request,
+                    BodyHandlers.discarding());
+            final List>> tasks = new ArrayList<>();
+            final int numAdditionalReqs = 20;
+            for (int i = 0; i < numAdditionalReqs; i++) {
+                tasks.add(task);
+            }
+            // issue the first request
+            System.err.println("issuing first request: " + request);
+            final HttpResponse firstResp = client.send(request, BodyHandlers.discarding());
+            assertEquals(200, firstResp.statusCode(), "unexpected response code for request "
+                    + request);
+            System.err.println("waiting for " + waitTimeMillis + " milli seconds" +
+                    " before issuing additional requests");
+            Thread.sleep(waitTimeMillis);
+            // issue additional concurrent requests
+            final List>> responses;
+            try (final ExecutorService executor = Executors.newFixedThreadPool(numAdditionalReqs)) {
+                responses = executor.invokeAll(tasks);
+            }
+            System.err.println("All " + responses.size() + " requests completed, now" +
+                    " verifying each response");
+            // verify all requests succeeded
+            for (final Future> future : responses) {
+                final HttpResponse rsp = future.get();
+                assertEquals(200, rsp.statusCode(), "unexpected response code for request "
+                        + request);
+            }
+        }
+    }
+
+    // returns the effective idle timeout duration of a HTTP2 connection
+    private static Duration getEffectiveH2IdleTimeoutDuration() {
+        final long keepAliveTimeoutInSecs = getNetProp(KEEPALIVE_TIMEOUT_PROP, 30);
+        final long h2TimeoutInSecs = getNetProp(H2_KEEPALIVE_TIMEOUT_PROP, keepAliveTimeoutInSecs);
+        return Duration.of(h2TimeoutInSecs, ChronoUnit.SECONDS);
+    }
+
+    private static long getNetProp(final String prop, final long def) {
+        final String s = Utils.getNetProperty(prop);
+        if (s == null) {
+            return def;
+        }
+        try {
+            final long timeoutVal = Long.parseLong(s);
+            return timeoutVal >= 0 ? timeoutVal : def;
+        } catch (NumberFormatException ignored) {
+            return def;
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/net/spi/InetAddressResolverProvider/RuntimePermissionTest.java openjdk-21-21.0.2+13/test/jdk/java/net/spi/InetAddressResolverProvider/RuntimePermissionTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/net/spi/InetAddressResolverProvider/RuntimePermissionTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/net/spi/InetAddressResolverProvider/RuntimePermissionTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, 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
@@ -63,7 +63,7 @@
                 ServiceConfigurationError sce =
                         Assert.expectThrows(ServiceConfigurationError.class,
                                             () -> InetAddress.getByName("javaTest.org"));
-                LOGGER.info("Got ServiceConfigurationError: " + sce);
+                System.err.println("Got ServiceConfigurationError: " + sce);
                 Throwable cause = sce.getCause();
                 Assert.assertTrue(cause instanceof SecurityException);
                 Assert.assertTrue(cause.getMessage().contains(RUNTIME_PERMISSION_NAME));
@@ -78,23 +78,25 @@
 
         public TestSecurityManager(boolean permitInetAddressResolver) {
             this.permitInetAddressResolver = permitInetAddressResolver;
-            LOGGER.info("inetAddressResolverProvider permission is " +
-                        (permitInetAddressResolver ? "granted" : "not granted"));
+            System.err.println("inetAddressResolverProvider permission is " +
+                               (permitInetAddressResolver ? "granted" : "not granted"));
         }
 
         @Override
         public void checkPermission(Permission permission) {
             if (permission instanceof RuntimePermission) {
-                LOGGER.info("Checking RuntimePermission: " + permission);
                 if (RUNTIME_PERMISSION_NAME.equals(permission.getName()) && !permitInetAddressResolver) {
-                    LOGGER.info("Denying '" + RUNTIME_PERMISSION_NAME + "' permission");
+                    System.err.println("Denying '" + RUNTIME_PERMISSION_NAME + "' permission");
                     throw new SecurityException("Access Denied: " + RUNTIME_PERMISSION_NAME);
-                }
+                } else {
+                   // Do not do anything for non-matching Permission. Otherwise the test
+                   // has a chance to re-enter here recursively, e.g. due to permission
+                   // checks during class load. This would eventually overflow the stack.
+               }
             }
         }
     }
 
     private static final String RUNTIME_PERMISSION_NAME = "inetAddressResolverProvider";
-    private static final Logger LOGGER = Logger.getLogger(RuntimePermissionTest.class.getName());
 
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/nio/channels/DatagramChannel/SendReceiveMaxSize.java openjdk-21-21.0.2+13/test/jdk/java/nio/channels/DatagramChannel/SendReceiveMaxSize.java
--- openjdk-21-21.0.1+12/test/jdk/java/nio/channels/DatagramChannel/SendReceiveMaxSize.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/nio/channels/DatagramChannel/SendReceiveMaxSize.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -55,6 +55,7 @@
 import static java.net.StandardProtocolFamily.INET;
 import static java.net.StandardProtocolFamily.INET6;
 import static java.net.StandardSocketOptions.SO_SNDBUF;
+import static java.net.StandardSocketOptions.SO_RCVBUF;
 import static jdk.test.lib.net.IPSupport.hasIPv4;
 import static jdk.test.lib.net.IPSupport.hasIPv6;
 import static jdk.test.lib.net.IPSupport.preferIPv4Stack;
@@ -63,8 +64,6 @@
 import static org.testng.Assert.assertTrue;
 
 public class SendReceiveMaxSize {
-    private final static int IPV4_SNDBUF = 65507;
-    private final static int IPV6_SNDBUF = 65527;
     private final static Class IOE = IOException.class;
     private final static Random random = RandomFactory.getRandom();
 
@@ -89,12 +88,12 @@
                     .orElse((Inet4Address) InetAddress.getByName("127.0.0.1"));
             testcases.add(new Object[]{
                     supplier(() -> DatagramChannel.open()),
-                    IPV4_SNDBUF,
+                    IPSupport.getMaxUDPSendBufSizeIPv4(),
                     IPv4Addr
             });
             testcases.add(new Object[]{
                     supplier(() -> DatagramChannel.open(INET)),
-                    IPV4_SNDBUF,
+                    IPSupport.getMaxUDPSendBufSizeIPv4(),
                     IPv4Addr
             });
         }
@@ -105,12 +104,12 @@
                     .orElse((Inet6Address) InetAddress.getByName("::1"));
             testcases.add(new Object[]{
                     supplier(() -> DatagramChannel.open()),
-                    IPV6_SNDBUF,
+                    IPSupport.getMaxUDPSendBufSizeIPv6(),
                     IPv6Addr
             });
             testcases.add(new Object[]{
                     supplier(() -> DatagramChannel.open(INET6)),
-                    IPV6_SNDBUF,
+                    IPSupport.getMaxUDPSendBufSizeIPv6(),
                     IPv6Addr
             });
         }
@@ -132,6 +131,10 @@
             throws IOException {
         try (var receiver = DatagramChannel.open()) {
             receiver.bind(new InetSocketAddress(host, 0));
+            assertTrue(receiver.getOption(SO_RCVBUF) >= capacity,
+                       receiver.getOption(SO_RCVBUF) +
+                       " for UDP receive buffer too small to hold capacity " +
+                       capacity);
             var port = receiver.socket().getLocalPort();
             var addr = new InetSocketAddress(host, port);
 
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java openjdk-21-21.0.2+13/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java
--- openjdk-21-21.0.1+12/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2021, 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
@@ -22,9 +22,10 @@
  */
 
 /* @test
- * @bug 8054029
+ * @bug 8054029 8313368
  * @requires (os.family == "linux")
  * @summary Block devices should not report size=0 on Linux
+ * @run main/manual BlockDeviceSize
  */
 
 import java.io.RandomAccessFile;
@@ -56,8 +57,8 @@
             System.err.println("File " + BLK_FNAME + " not found." +
                     " Skipping test");
         } catch (AccessDeniedException ade) {
-            System.err.println("Access to " + BLK_FNAME + " is denied." +
-                    " Run test as root.");
+            throw new RuntimeException("Access to " + BLK_FNAME + " is denied."
+                    + " Run test as root.", ade);
         }
     }
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/nio/file/Files/CopyAndMove.java openjdk-21-21.0.2+13/test/jdk/java/nio/file/Files/CopyAndMove.java
--- openjdk-21-21.0.1+12/test/jdk/java/nio/file/Files/CopyAndMove.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/nio/file/Files/CopyAndMove.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2022, 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
@@ -909,7 +909,7 @@
         if (supportsLinks) {
             source = createSourceFile(dir1);
             link = dir1.resolve("link");
-            createSymbolicLink(link, source);
+            createSymbolicLink(link, source.getFileName());
             target = getTargetFile(dir2);
             copyAndVerify(link, target);
             delete(link);
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java openjdk-21-21.0.2+13/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java
--- openjdk-21-21.0.1+12/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java	2024-01-16 16:19:00.000000000 +0000
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 8011536 8151430
+ * @bug 8011536 8151430 8316304
  * @summary Basic test for creationTime attribute on platforms/file systems
  *     that support it.
  * @library  ../.. /test/lib
@@ -88,7 +88,13 @@
                 supportsCreationTimeRead = true;
                 supportsCreationTimeWrite = true;
             }
+        } else if (Platform.isLinux()) {
+            // Creation time read depends on statx system call support
+            supportsCreationTimeRead = CreationTimeHelper.linuxIsCreationTimeSupported();
+            // Creation time updates are not supported on Linux
+            supportsCreationTimeWrite = false;
         }
+        System.out.println("supportsCreationTimeRead == " + supportsCreationTimeRead);
 
         /**
          * If the creation-time attribute is supported then change the file's
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTimeHelper.java openjdk-21-21.0.2+13/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTimeHelper.java
--- openjdk-21-21.0.1+12/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTimeHelper.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTimeHelper.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+public class CreationTimeHelper {
+
+    static {
+        System.loadLibrary("CreationTimeHelper");
+    }
+
+    // Helper so as to determine 'statx' support on the runtime system
+    static native boolean linuxIsCreationTimeSupported();
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/nio/file/attribute/BasicFileAttributeView/libCreationTimeHelper.c openjdk-21-21.0.2+13/test/jdk/java/nio/file/attribute/BasicFileAttributeView/libCreationTimeHelper.c
--- openjdk-21-21.0.1+12/test/jdk/java/nio/file/attribute/BasicFileAttributeView/libCreationTimeHelper.c	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/nio/file/attribute/BasicFileAttributeView/libCreationTimeHelper.c	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2023, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include "jni.h"
+#if defined(__linux__)
+#include 
+#endif
+
+// static native boolean linuxIsCreationTimeSupported()
+JNIEXPORT jboolean JNICALL
+Java_CreationTimeHelper_linuxIsCreationTimeSupported(JNIEnv *env, jclass cls)
+{
+#if defined(__linux__)
+    void* statx_func = dlsym(RTLD_DEFAULT, "statx");
+    return statx_func != NULL ? JNI_TRUE : JNI_FALSE;
+#else
+    return JNI_FALSE;
+#endif
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/util/Properties/StoreReproducibilityTest.java openjdk-21-21.0.2+13/test/jdk/java/util/Properties/StoreReproducibilityTest.java
--- openjdk-21-21.0.1+12/test/jdk/java/util/Properties/StoreReproducibilityTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/util/Properties/StoreReproducibilityTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -44,7 +44,7 @@
 /*
  * @test
  * @summary Tests that the Properties.store() APIs generate output that is reproducible
- * @bug 8231640 8282023
+ * @bug 8231640 8282023 8316540
  * @library /test/lib
  * @run driver StoreReproducibilityTest
  */
@@ -92,7 +92,7 @@
         for (int i = 0; i < 5; i++) {
             final Path tmpFile = Files.createTempFile("8231640", ".props");
             storedFiles.add(tmpFile);
-            final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+            final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
                     "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
                     StoreTest.class.getName(),
                     tmpFile.toString(),
@@ -134,10 +134,10 @@
         for (int i = 0; i < 5; i++) {
             final Path tmpFile = Files.createTempFile("8231640", ".props");
             storedFiles.add(tmpFile);
-            final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+            final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
                     "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
                     "-Djava.security.manager",
-                    "-Djava.security.policy=" + policyFile.toString(),
+                    "-Djava.security.policy=" + policyFile,
                     StoreTest.class.getName(),
                     tmpFile.toString(),
                     i % 2 == 0 ? "--use-outputstream" : "--use-writer");
@@ -178,10 +178,10 @@
         for (int i = 0; i < 5; i++) {
             final Path tmpFile = Files.createTempFile("8231640", ".props");
             storedFiles.add(tmpFile);
-            final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+            final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
                     "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
                     "-Djava.security.manager",
-                    "-Djava.security.policy=" + policyFile.toString(),
+                    "-Djava.security.policy=" + policyFile,
                     StoreTest.class.getName(),
                     tmpFile.toString(),
                     i % 2 == 0 ? "--use-outputstream" : "--use-writer");
@@ -208,7 +208,7 @@
         for (int i = 0; i < 2; i++) {
             final Path tmpFile = Files.createTempFile("8231640", ".props");
             storedFiles.add(tmpFile);
-            final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+            final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
                     "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
                     StoreTest.class.getName(),
                     tmpFile.toString(),
@@ -240,8 +240,9 @@
     private static void testEmptySysPropValue() throws Exception {
         for (int i = 0; i < 2; i++) {
             final Path tmpFile = Files.createTempFile("8231640", ".props");
-            final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
-                    "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + "",
+            final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
+                    "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=",
+                    "-Duser.timezone=UTC",
                     StoreTest.class.getName(),
                     tmpFile.toString(),
                     i % 2 == 0 ? "--use-outputstream" : "--use-writer");
@@ -271,7 +272,7 @@
         for (int i = 0; i < 2; i++) {
             final Path tmpFile = Files.createTempFile("8231640", ".props");
             storedFiles.add(tmpFile);
-            final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+            final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
                     "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
                     StoreTest.class.getName(),
                     tmpFile.toString(),
@@ -300,7 +301,7 @@
             for (int i = 0; i < 2; i++) {
                 final Path tmpFile = Files.createTempFile("8231640", ".props");
                 storedFiles.add(tmpFile);
-                final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+                final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
                         "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
                         StoreTest.class.getName(),
                         tmpFile.toString(),
@@ -342,7 +343,7 @@
             for (int i = 0; i < 2; i++) {
                 final Path tmpFile = Files.createTempFile("8231640", ".props");
                 storedFiles.add(tmpFile);
-                final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+                final ProcessBuilder processBuilder = ProcessTools.createTestJvm(
                         "-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
                         StoreTest.class.getName(),
                         tmpFile.toString(),
@@ -416,6 +417,9 @@
      * Verifies that the date comment in the {@code destFile} can be parsed using the
      * "EEE MMM dd HH:mm:ss zzz uuuu" format and the time represented by it is {@link Date#after(Date) after}
      * the passed {@code date}
+     * The JVM runtime to invoke this method should set the time zone to UTC, i.e, specify
+     * "-Duser.timezone=UTC" at the command line. Otherwise, it will fail with some time
+     * zones that have ambiguous short names, such as "IST"
      */
     private static void assertCurrentDate(final Path destFile, final Date date) throws Exception {
         final String dateComment = findNthComment(destFile, 2);
@@ -440,7 +444,7 @@
     private static String findNthComment(Path file, int commentIndex) throws IOException {
         List comments = new ArrayList<>();
         try (final BufferedReader reader = Files.newBufferedReader(file)) {
-            String line = null;
+            String line;
             while ((line = reader.readLine()) != null) {
                 if (line.startsWith("#")) {
                     comments.add(line.substring(1));
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/util/Random/RandomTestBsi1999.java openjdk-21-21.0.2+13/test/jdk/java/util/Random/RandomTestBsi1999.java
--- openjdk-21-21.0.1+12/test/jdk/java/util/Random/RandomTestBsi1999.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/util/Random/RandomTestBsi1999.java	2024-01-16 16:19:00.000000000 +0000
@@ -43,9 +43,9 @@
 
 /**
  * @test
- * @summary test bit sequences produced by clases that implement interface RandomGenerator
+ * @summary test bit sequences produced by classes that implement interface RandomGenerator
  * @bug 8248862
- * @run main RandomTestBsi1999
+ * @run main/othervm/timeout=400 RandomTestBsi1999
  * @key randomness
  */
 
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java openjdk-21-21.0.2+13/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java
--- openjdk-21-21.0.1+12/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java	2024-01-16 16:19:00.000000000 +0000
@@ -51,7 +51,7 @@
  * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch == "ppc64" | os.arch == "ppc64le" | os.arch == "riscv64" | os.arch == "s390x"
  * @requires vm.debug
  * @library /test/lib
- * @run main/othervm/timeout=1600 -XX:+UseHeavyMonitors -XX:+VerifyHeavyMonitors MapLoops
+ * @run main/othervm/timeout=1600 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=0 -XX:+VerifyHeavyMonitors MapLoops
  */
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/util/concurrent/LinkedTransferQueue/WhiteBox.java openjdk-21-21.0.2+13/test/jdk/java/util/concurrent/LinkedTransferQueue/WhiteBox.java
--- openjdk-21-21.0.1+12/test/jdk/java/util/concurrent/LinkedTransferQueue/WhiteBox.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/util/concurrent/LinkedTransferQueue/WhiteBox.java	2024-01-16 16:19:00.000000000 +0000
@@ -59,18 +59,24 @@
 
 @Test
 public class WhiteBox {
+
     final ThreadLocalRandom rnd = ThreadLocalRandom.current();
     final VarHandle HEAD, TAIL, ITEM, NEXT;
 
-    public WhiteBox() throws ReflectiveOperationException {
-        Class qClass = LinkedTransferQueue.class;
-        Class nodeClass = Class.forName(qClass.getName() + "$Node");
-        MethodHandles.Lookup lookup
-            = MethodHandles.privateLookupIn(qClass, MethodHandles.lookup());
-        HEAD = lookup.findVarHandle(qClass, "head", nodeClass);
-        TAIL = lookup.findVarHandle(qClass, "tail", nodeClass);
-        NEXT = lookup.findVarHandle(nodeClass, "next", nodeClass);
-        ITEM = lookup.findVarHandle(nodeClass, "item", Object.class);
+    public WhiteBox() throws Throwable { // throws ReflectiveOperationException {
+        try {
+            Class qClass = LinkedTransferQueue.class;
+            Class nodeClass = Class.forName(qClass.getName() + "$DualNode");
+            MethodHandles.Lookup lookup
+                = MethodHandles.privateLookupIn(qClass, MethodHandles.lookup());
+            HEAD = lookup.findVarHandle(qClass, "head", nodeClass);
+            TAIL = lookup.findVarHandle(qClass, "tail", nodeClass);
+            NEXT = lookup.findVarHandle(nodeClass, "next", nodeClass);
+            ITEM = lookup.findVarHandle(nodeClass, "item", Object.class);
+        } catch (Throwable ex) {
+            ex.printStackTrace();
+            throw ex;
+        }
     }
 
     Object head(LinkedTransferQueue q) { return HEAD.getVolatile(q); }
@@ -78,6 +84,16 @@
     Object item(Object node)           { return ITEM.getVolatile(node); }
     Object next(Object node)           { return NEXT.getVolatile(node); }
 
+    /*
+     * Modified for jdk22: Accommodate lazy initialization, so counts
+     * may vary by 1, and some nodes become headers vs unlinked,
+     * compared to previous versions.
+     */
+
+    static void checkCount(int val, int expect) {
+        assertTrue(val == expect || val == expect - 1);
+    }
+
     int nodeCount(LinkedTransferQueue q) {
         int i = 0;
         for (Object p = head(q); p != null; ) {
@@ -124,13 +140,15 @@
     public void addRemove() {
         LinkedTransferQueue q = new LinkedTransferQueue();
         assertInvariants(q);
-        assertNull(next(head(q)));
-        assertNull(item(head(q)));
+        if (head(q) != null) {
+            assertNull(next(head(q)));
+            assertNull(item(head(q)));
+        }
         q.add(1);
-        assertEquals(nodeCount(q), 2);
+        checkCount(nodeCount(q), 2);
         assertInvariants(q);
         q.remove(1);
-        assertEquals(nodeCount(q), 1);
+        checkCount(nodeCount(q), 1);
         assertInvariants(q);
     }
 
@@ -158,12 +176,12 @@
         Object oldHead;
         int n = 1 + rnd.nextInt(5);
         for (int i = 0; i < n; i++) q.add(i);
-        assertEquals(nodeCount(q), n + 1);
+        checkCount(nodeCount(q), n + 1);
         oldHead = head(q);
         traversalAction.accept(q);
         assertInvariants(q);
-        assertEquals(nodeCount(q), n);
-        assertIsSelfLinked(oldHead);
+        checkCount(nodeCount(q), n);
+        //        assertIsSelfLinked(oldHead);
     }
 
     @Test(dataProvider = "traversalActions")
@@ -204,7 +222,7 @@
 
         int c = nodeCount(q);
         traversalAction.accept(q);
-        assertEquals(nodeCount(q), c - 1);
+        checkCount(nodeCount(q), c - 1);
 
         assertSame(next(p0), p4);
         assertSame(next(p1), p4);
@@ -217,7 +235,7 @@
         traversalAction.accept(q);
         assertSame(next(p4), p5);
         assertNull(next(p5));
-        assertEquals(nodeCount(q), c - 1);
+        checkCount(nodeCount(q), c - 1);
     }
 
     /**
@@ -228,7 +246,7 @@
     public void traversalOperationsCollapseRandomNodes(
         Consumer traversalAction) {
         LinkedTransferQueue q = new LinkedTransferQueue();
-        int n = rnd.nextInt(6);
+        int n = 1 + rnd.nextInt(6);
         for (int i = 0; i < n; i++) q.add(i);
         ArrayList nulledOut = new ArrayList();
         for (Object p = head(q); p != null; p = next(p))
@@ -238,7 +256,7 @@
             }
         traversalAction.accept(q);
         int c = nodeCount(q);
-        assertEquals(q.size(), c - (q.contains(n - 1) ? 0 : 1));
+        checkCount(c - (q.contains(n - 1) ? 0 : 1), q.size() + 1);
         for (int i = 0; i < n; i++)
             assertTrue(nulledOut.contains(i) ^ q.contains(i));
     }
@@ -263,7 +281,7 @@
         int n = 1 + rnd.nextInt(5);
         for (int i = 0; i < n; i++) q.add(i);
         bulkRemovalAction.accept(q);
-        assertEquals(nodeCount(q), 1);
+        checkCount(nodeCount(q), 1);
         assertInvariants(q);
     }
 
@@ -289,13 +307,13 @@
         LinkedTransferQueue q = new LinkedTransferQueue();
         int n = 1 + rnd.nextInt(5);
         for (int i = 0; i < n; i++) q.add(i);
-        assertEquals(nodeCount(q), n + 1);
+        checkCount(nodeCount(q), n + 1);
         for (int i = 0; i < n; i++) {
             int c = nodeCount(q);
             boolean slack = item(head(q)) == null;
             if (slack) assertNotNull(item(next(head(q))));
             pollAction.accept(q);
-            assertEquals(nodeCount(q), q.isEmpty() ? 1 : c - (slack ? 2 : 0));
+            checkCount(nodeCount(q), q.isEmpty() ? 1 : c - (slack ? 2 : 0));
         }
         assertInvariants(q);
     }
@@ -318,11 +336,12 @@
         LinkedTransferQueue q = new LinkedTransferQueue();
         int n = 1 + rnd.nextInt(9);
         for (int i = 0; i < n; i++) {
-            boolean slack = next(tail(q)) != null;
+            boolean empty = (tail(q) == null);
+            boolean slack = !empty && (next(tail(q)) != null);
             addAction.accept(q);
             if (slack)
                 assertNull(next(tail(q)));
-            else {
+            else if (!empty) {
                 assertNotNull(next(tail(q)));
                 assertNull(next(next(tail(q))));
             }
@@ -365,10 +384,9 @@
 
     /** Checks conditions which should always be true. */
     void assertInvariants(LinkedTransferQueue q) {
-        assertNotNull(head(q));
-        assertNotNull(tail(q));
         // head is never self-linked (but tail may!)
-        for (Object h; next(h = head(q)) == h; )
-            assertNotSame(h, head(q)); // must be update race
+        Object h;
+        if ((h = head(q)) != null)
+            assertNotSame(h, next(h));
     }
 }
diff -Nru openjdk-21-21.0.1+12/test/jdk/java/util/concurrent/tck/JSR166TestCase.java openjdk-21-21.0.2+13/test/jdk/java/util/concurrent/tck/JSR166TestCase.java
--- openjdk-21-21.0.1+12/test/jdk/java/util/concurrent/tck/JSR166TestCase.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/java/util/concurrent/tck/JSR166TestCase.java	2024-01-16 16:19:00.000000000 +0000
@@ -35,31 +35,54 @@
  */
 
 /*
- * @test
- * @summary JSR-166 tck tests, in a number of variations.
- *          The first is the conformance testing variant,
- *          while others also test implementation details.
+ * @test id=default
+ * @summary Conformance testing variant of JSR-166 tck tests.
  * @build *
  * @modules java.management
  * @run junit/othervm/timeout=1000 JSR166TestCase
+ */
+
+/*
+ * @test id=security-manager
+ * @summary Conformance testing variant of JSR-166 tck tests
+ *          with java security manager set to allow.
+ * @build *
+ * @modules java.management
  * @run junit/othervm/timeout=1000 -Djava.security.manager=allow JSR166TestCase
+ */
+
+/*
+ * @test id=forkjoinpool-common-parallelism
+ * @summary Test implementation details variant of JSR-166
+ *          tck tests with ForkJoinPool common parallelism.
+ * @build *
+ * @modules java.management
  * @run junit/othervm/timeout=1000
  *      --add-opens java.base/java.util.concurrent=ALL-UNNAMED
  *      --add-opens java.base/java.lang=ALL-UNNAMED
  *      -Djsr166.testImplementationDetails=true
+ *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=0
  *      JSR166TestCase
  * @run junit/othervm/timeout=1000
  *      --add-opens java.base/java.util.concurrent=ALL-UNNAMED
  *      --add-opens java.base/java.lang=ALL-UNNAMED
  *      -Djsr166.testImplementationDetails=true
- *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=0
+ *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
+ *      -Djava.util.secureRandomSeed=true
  *      JSR166TestCase
+ */
+
+/*
+ * @test id=others
+ * @summary Remaining test implementation details variant of
+ *          JSR-166 tck tests apart from ForkJoinPool common
+ *          parallelism.
+ * @build *
+ * @modules java.management
  * @run junit/othervm/timeout=1000
  *      --add-opens java.base/java.util.concurrent=ALL-UNNAMED
  *      --add-opens java.base/java.lang=ALL-UNNAMED
  *      -Djsr166.testImplementationDetails=true
- *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
- *      -Djava.util.secureRandomSeed=true
  *      JSR166TestCase
  * @run junit/othervm/timeout=1000/policy=tck.policy
  *      --add-opens java.base/java.util.concurrent=ALL-UNNAMED
diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/net/ssl/TLSCommon/SSLEngineTestCase.java openjdk-21-21.0.2+13/test/jdk/javax/net/ssl/TLSCommon/SSLEngineTestCase.java
--- openjdk-21-21.0.1+12/test/jdk/javax/net/ssl/TLSCommon/SSLEngineTestCase.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/javax/net/ssl/TLSCommon/SSLEngineTestCase.java	2024-01-16 16:19:00.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, 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
@@ -134,7 +134,7 @@
      * e.g. "TLSv1", "TLSv1.1", "TLSv1.2", "DTLSv1.0", "DTLSv1.2".
      */
     public static final String TESTED_SECURITY_PROTOCOL
-            = System.getProperty("test.security.protocol", "TLS");
+            = System.getProperty("test.security.protocol");
     /**
      * Test mode: "norm", "norm_sni" or "krb".
      * Modes "norm" and "norm_sni" are used to run
@@ -738,13 +738,18 @@
                     case "TLSv1.1":
                         runTests(Ciphers.SUPPORTED_NON_KRB_NON_SHA_CIPHERS);
                         break;
-                    case "DTLSv1.1":
+                    case "DTLS":
+                    case "DTLSv1.2":
+                    case "TLS":
                     case "TLSv1.2":
                         runTests(Ciphers.SUPPORTED_NON_KRB_CIPHERS);
                         break;
                     case "TLSv1.3":
                         runTests(Ciphers.TLS13_CIPHERS);
                         break;
+                    default:
+                        throw new Error("Test error: Unsupported test " +
+                                "security protocol: " + TESTED_SECURITY_PROTOCOL);
                 }
                 break;
             case "krb":
diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/sound/sampled/Lines/OpenLineAfterScreenLock.java openjdk-21-21.0.2+13/test/jdk/javax/sound/sampled/Lines/OpenLineAfterScreenLock.java
--- openjdk-21-21.0.1+12/test/jdk/javax/sound/sampled/Lines/OpenLineAfterScreenLock.java	1970-01-01 00:00:00.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/javax/sound/sampled/Lines/OpenLineAfterScreenLock.java	2024-01-16 16:19:00.000000000 +0000
@@ -0,0 +1,144 @@
+/*
+ * 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.awt.BorderLayout;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.TargetDataLine;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import static javax.swing.SwingUtilities.invokeAndWait;
+
+/*
+ * @test
+ * @bug 8301846
+ * @requires (os.family == "windows")
+ * @summary Sound recording fails after screen lock and unlock.
+ * @run main/manual OpenLineAfterScreenLock
+ */
+public class OpenLineAfterScreenLock {
+
+    private static final String INSTRUCTIONS = """
+            This test verifies it can record sound from the first sound capture device after
+            locking and unlocking the screen. The first part of the test has already completed.
+
+            Lock the screen and unlock it. Then click Continue to complete the test.
+
+            The test will finish automatically.
+            """;
+
+    private static final CountDownLatch latch = new CountDownLatch(1);
+
+    private static JFrame frame;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            runTest();
+
+            // Creating JFileChooser initializes COM
+            // which affects ability to open audio lines
+            new JFileChooser();
+
+            invokeAndWait(OpenLineAfterScreenLock::createInstructionsUI);
+            if (!latch.await(2, TimeUnit.MINUTES)) {
+                throw new RuntimeException("Test failed: Test timed out!!");
+            }
+
+            runTest();
+        } finally {
+            invokeAndWait(() -> {
+                if (frame != null) {
+                    frame.dispose();
+                }
+            });
+        }
+        System.out.println("Test Passed");
+    }
+
+    private static void runTest() {
+        try {
+            Mixer mixer = getMixer();
+            TargetDataLine line =
+                    (TargetDataLine) mixer.getLine(mixer.getTargetLineInfo()[0]);
+            line.open();
+            line.close();
+        } catch (LineUnavailableException e) {
+            throw new RuntimeException("Test failed: Line unavailable", e);
+        }
+    }
+
+    private static Mixer getMixer() {
+        return Arrays.stream(AudioSystem.getMixerInfo())
+                     .map(AudioSystem::getMixer)
+                     .filter(OpenLineAfterScreenLock::isRecordingDevice)
+                     .skip(1) // Skip the primary driver and choose one directly
+                     .findAny()
+                     .orElseThrow();
+    }
+
+    private static boolean isRecordingDevice(Mixer mixer) {
+        Line.Info[] lineInfos = mixer.getTargetLineInfo();
+        return lineInfos.length > 0
+               && lineInfos[0].getLineClass() == TargetDataLine.class;
+    }
+
+    private static void createInstructionsUI() {
+        frame = new JFrame("Instructions for OpenLineAfterScreenLock");
+
+        JTextArea textArea = new JTextArea(INSTRUCTIONS);
+        textArea.setEditable(false);
+
+        JScrollPane pane = new JScrollPane(textArea);
+        frame.getContentPane().add(pane, BorderLayout.NORTH);
+
+        JButton button = new JButton("Continue");
+        button.addActionListener(e -> latch.countDown());
+        frame.getContentPane().add(button, BorderLayout.PAGE_END);
+
+        frame.pack();
+        frame.setLocationRelativeTo(null);
+
+        frame.addWindowListener(new CloseWindowHandler());
+        frame.setVisible(true);
+    }
+
+    private static class CloseWindowHandler extends WindowAdapter {
+        @Override
+        public void windowClosing(WindowEvent e) {
+            latch.countDown();
+            throw new RuntimeException("Test window closed abruptly");
+        }
+    }
+}
diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java openjdk-21-21.0.2+13/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java
--- openjdk-21-21.0.1+12/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java	2023-10-05 13:08:46.000000000 +0000
+++ openjdk-21-21.0.2+13/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java	2024-01-16 16:19:00.000000000 +0000
@@ -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
@@ -22,21 +22,21 @@
  */
 
 import java.awt.BorderLayout;
+import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
-import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
+import java.util.List;
 
 import javax.swing.JCheckBox;
 import javax.swing.JFileChooser;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
-import javax.swing.JTextArea;
 import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
+import javax.swing.JTextArea;
 import javax.swing.WindowConstants;
 
 /*
@@ -51,74 +51,80 @@
  * @run main/manual FileChooserSymLinkTest
  */
 public class FileChooserSymLinkTest {
+    private static final String INSTRUCTIONS = """
+            
+            Instructions to Test:
+            
    +
  1. Open an elevated Command Prompt. +
  2. Paste the following commands: +
    cd /d C:\\
    +            mkdir FileChooserTest
    +            cd FileChooserTest
    +            mkdir target
    +            mklink /d link target
    + +
  3. Navigate to C:\\FileChooserTest in + the JFileChooser. +
  4. Perform testing in single- and multi-selection modes: +
      +
    • Single-selection: +
        +
      1. Ensure Enable multi-selection is cleared + (the default state). +
      2. Click link directory, + the absolute path of the symbolic + link should be displayed.
        + If it's null, click Fail. +
      3. Click target directory, + its absolute path should be displayed. +
      +
    • Multi-selection: +
        +
      1. Select Enable multi-selection. +
      2. Click link, +
      3. Press Ctrl and + then click target. +
      4. Both should be selected and + their absolute paths should be displayed. +
      5. If link can't be selected or + if its absolute path is null, + click Fail. +
      +
    +

    If link can be selected in both + single- and multi-selection modes, click Pass.

    +
  5. When done with testing, paste the following commands to + remove the FileChooserTest directory: +
    cd \\
    +            rmdir /s /q C:\\FileChooserTest
    + + or use File Explorer to clean it up. +
+ """; + static JFrame frame; static JFileChooser jfc; static JPanel panel; static JTextArea pathList; static JCheckBox multiSelection; - static PassFailJFrame passFailJFrame; public static void main(String[] args) throws Exception { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - try { - initialize(); - } catch (InterruptedException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - }); - passFailJFrame.awaitAndCheck(); + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .rows(35) + .columns(50) + .testUI(FileChooserSymLinkTest::createTestUI) + .build() + .awaitAndCheck(); } - static void initialize() throws InterruptedException, InvocationTargetException { - //Initialize the components - final String INSTRUCTIONS = """ - Instructions to Test: - 1. Open an elevated Command Prompt. - 2. Paste the following commands: - cd /d C:\\ - mkdir FileChooserTest - cd FileChooserTest - mkdir target - mklink /d link target - - 3. Navigate to C:\\FileChooserTest in the JFileChooser. - 4. Use "Enable Multi-Selection" checkbox to enable/disable - MultiSelection Mode - 5. Single-selection: - Click "link" directory, the absolute path of the symbolic - link should be displayed. If it's null, click FAIL. - Click "target" directory, its absolute path should be - displayed. - - Enable multiple selection by clicking the checkbox. - Multi-selection: - Click "link", press Ctrl and then click "target". - Both should be selected and their absolute paths should be - displayed. - - If "link" can't be selected or if its absolute path is null, - click FAIL. - - If "link" can be selected in both single- and multi-selection modes, - click PASS. - 6. When done with testing, paste the following commands to - remove the 'FileChooserTest' directory: - cd \\ - rmdir /s /q C:\\FileChooserTest - - or use File Explorer to clean it up. - """; + private static List createTestUI() { frame = new JFrame("JFileChooser Symbolic Link test"); panel = new JPanel(new BorderLayout()); multiSelection = new JCheckBox("Enable Multi-Selection"); pathList = new JTextArea(10, 50); jfc = new JFileChooser(new File("C:\\")); - passFailJFrame = new PassFailJFrame("Test Instructions", INSTRUCTIONS, 5L, 35, 40); - PassFailJFrame.addTestWindow(frame); - PassFailJFrame.positionTestWindow(frame, PassFailJFrame.Position.HORIZONTAL); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); panel.add(multiSelection, BorderLayout.EAST); panel.add(new JScrollPane(pathList), BorderLayout.WEST); @@ -153,6 +159,6 @@ frame.add(panel, BorderLayout.NORTH); frame.add(jfc, BorderLayout.CENTER); frame.pack(); - frame.setVisible(true); + return List.of(frame); } } diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/swing/JMenuItem/8031573/bug8031573.java openjdk-21-21.0.2+13/test/jdk/javax/swing/JMenuItem/8031573/bug8031573.java --- openjdk-21-21.0.1+12/test/jdk/javax/swing/JMenuItem/8031573/bug8031573.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/javax/swing/JMenuItem/8031573/bug8031573.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -32,18 +32,18 @@ import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; -import javax.swing.JMenuItem; import javax.swing.JPanel; +import javax.swing.JRadioButtonMenuItem; import javax.swing.JTextArea; -import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.text.JTextComponent; /* @test - * @bug 8031573 8040279 8143064 - * @summary [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered + * @bug 8031573 8040279 8143064 8294427 + * @summary Checkmarks of JCheckBoxMenuItems aren't rendered * in high resolution on Retina + * @requires (os.family != "linux") * @run main/manual bug8031573 */ @@ -54,14 +54,21 @@ private static final CountDownLatch latch = new CountDownLatch(1); public static final String INSTRUCTIONS = "INSTRUCTIONS:\n\n" - + "Verify that high resolution system icons are used for JCheckBoxMenuItem on HiDPI displays.\n" - + "If the display does not support HiDPI mode press PASS.\n" - + "1. Run the test on HiDPI Display.\n" - + "2. Open the Menu.\n" - + "3. Check that the icon on the JCheckBoxMenuItem is smooth.\n" - + " If so, press PASS, else press FAIL.\n"; + + "Verify that the check and radio-check icons are rendered smoothly\n" + + "for both JCheckBoxMenuItem and JRadioButtonMenuItem.\n" + + "1. Open the Menu.\n" + + "2. Check that the icon on the JCheckBoxMenuItem is smooth.\n" + + "3. Check that the icon on the JRadioButtonMenuItem is smooth.\n" + + "4. If you're on Windows:\n" + + " Test the markers are still crisp after changing the scale in Windows settings.\n" + + " This could be done on same monitor by changing its scale or\n" + + " by moving the window to a secondary monitor with a different scale.\n" + + " Then go to step 6.\n" + + "5. If you're on Mac OS:\n" + + " If you tested on a Retina display, go to step 6.\n" + + "6. If both icons render smoothly, press PASS, otherwise press FAIL.\n"; - public static void main(String args[]) throws Exception { + public static void main(String[] args) throws Exception { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); try { SwingUtilities.invokeAndWait(() -> createTestGUI()); @@ -88,6 +95,9 @@ JCheckBoxMenuItem checkBoxMenuItem = new JCheckBoxMenuItem("JCheckBoxMenuItem"); checkBoxMenuItem.setSelected(true); menu.add(checkBoxMenuItem); + JRadioButtonMenuItem radioButtonMenuItem = new JRadioButtonMenuItem("JRadioButtonMenuItem"); + radioButtonMenuItem.setSelected(true); + menu.add(radioButtonMenuItem); bar.add(menu); frame.setJMenuBar(bar); diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java openjdk-21-21.0.2+13/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java --- openjdk-21-21.0.1+12/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2022, 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 @@ -21,19 +21,9 @@ * questions. */ -/* - * @test - * @key headful - * @bug 4529206 - * @summary JToolBar - setFloating does not work correctly - * @run main bug4529206 - */ - import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Robot; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; @@ -41,6 +31,14 @@ import javax.swing.JToolBar; import javax.swing.SwingUtilities; +/* + * @test + * @key headful + * @bug 4529206 + * @summary JToolBar - setFloating does not work correctly + * @run main bug4529206 + */ + public class bug4529206 { static JFrame frame; static JToolBar jToolBar1; @@ -58,11 +56,7 @@ JTextField tf = new JTextField("click here"); jPanFrame.add(tf); jToolBar1.add(jButton1, null); - jButton1.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - buttonPressed(e); - } - }); + jButton1.addActionListener(e -> buttonPressed()); frame.setUndecorated(true); frame.setLocationRelativeTo(null); @@ -77,32 +71,24 @@ } } - private static void buttonPressed(ActionEvent e) { + private static void buttonPressed() { makeToolbarFloat(); } public static void main(String[] args) throws Exception { try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - test(); - } - }); + SwingUtilities.invokeAndWait(() -> test()); Robot robot = new Robot(); - robot.waitForIdle(); + robot.setAutoWaitForIdle(true); robot.delay(1000); - SwingUtilities.invokeAndWait(() -> { - makeToolbarFloat(); - }); + SwingUtilities.invokeAndWait(() -> makeToolbarFloat()); + robot.delay(300); - robot.waitForIdle(); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - if (frame.isFocused()) { - throw - new RuntimeException("setFloating does not work correctly"); - } + SwingUtilities.invokeAndWait(() -> { + if (frame.isFocused()) { + throw + new RuntimeException("setFloating does not work correctly"); } }); } finally { diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4357975.java openjdk-21-21.0.2+13/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4357975.java --- openjdk-21-21.0.1+12/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4357975.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4357975.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * 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 4357975 + * @summary Tests if InsertUnorderedListItem generates the proper tag sequence + * @run main bug4357975 + */ + +import java.awt.event.ActionEvent; + +import javax.swing.Action; +import javax.swing.JEditorPane; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.AttributeSet; +import javax.swing.text.Element; +import javax.swing.text.StyleConstants; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.HTMLDocument; + +public class bug4357975 { + + public static void main(String[] args) throws Exception { + JEditorPane jep = new JEditorPane(); + HTMLEditorKit kit = new HTMLEditorKit(); + jep.setEditorKit(kit); + jep.setDocument(kit.createDefaultDocument()); + + HTMLDocument doc = (HTMLDocument) jep.getDocument(); + + DocumentListener l = new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + int offset = e.getOffset(); + HTMLDocument doc = (HTMLDocument)e.getDocument(); + + Element el = doc.getCharacterElement(offset + 1); + AttributeSet attrs = el.getAttributes(); + Object name = attrs.getAttribute(StyleConstants.NameAttribute); + boolean passed = (name == HTML.Tag.CONTENT); + + el = el.getParentElement(); + attrs = el.getAttributes(); + name = attrs.getAttribute(StyleConstants.NameAttribute); + passed = (passed && (name == HTML.Tag.IMPLIED)); + + el = el.getParentElement(); + attrs = el.getAttributes(); + name = attrs.getAttribute(StyleConstants.NameAttribute); + passed = (passed && (name == HTML.Tag.LI)); + + el = el.getParentElement(); + attrs = el.getAttributes(); + name = attrs.getAttribute(StyleConstants.NameAttribute); + passed = (passed && (name == HTML.Tag.UL)); + if (!passed) { + throw new RuntimeException("Test failed"); + } + } + + @Override + public void changedUpdate(DocumentEvent e) {} + @Override + public void removeUpdate(DocumentEvent e) {} + }; + doc.addDocumentListener(l); + + Action[] actions = kit.getActions(); + for (int i = 0; i < actions.length; i++){ + Action a = actions[i]; + if (a.getValue(Action.NAME) == "InsertUnorderedListItem") { + a.actionPerformed(new ActionEvent(jep, + ActionEvent.ACTION_PERFORMED, + (String) a.getValue(Action.ACTION_COMMAND_KEY))); + break; + } + } + + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/swing/text/html/HTMLWriter/bug4841760.java openjdk-21-21.0.2+13/test/jdk/javax/swing/text/html/HTMLWriter/bug4841760.java --- openjdk-21-21.0.1+12/test/jdk/javax/swing/text/html/HTMLWriter/bug4841760.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/javax/swing/text/html/HTMLWriter/bug4841760.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,67 @@ +/* + * 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 4841760 + * @summary Tests if HTML tags are correctly shown for + StyleEditorKit.ForegroundAction() in JTextPane output. + * @run main bug4841760 + */ + +import javax.swing.JTextPane; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4841760 { + + public static void main(String[] args) throws Exception { + JTextPane jep = new JTextPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setText("hellojavaworld"); + + SimpleAttributeSet set = new SimpleAttributeSet(); + StyleConstants.setForeground(set, java.awt.Color.BLUE); + jep.getStyledDocument().setCharacterAttributes(3, 5, set, false); + + String gotText = jep.getText(); + System.out.println("gotText: " + gotText); + // there should be color attribute set + // and 3 font tags + int i = gotText.indexOf("color"); + if (i > 0) { + i = gotText.indexOf(" 0) { + i = gotText.indexOf(" 0) { + i = gotText.indexOf(" { + bug4329185 test = new bug4329185(); + test.start(); + }); + robot.waitForIdle(); + robot.delay(1000); + boolean passed = ((views[0].getAlignment(View.Y_AXIS) == 0.0) + && (views[1].getAlignment(View.Y_AXIS) == 0.5) + && (views[2].getAlignment(View.Y_AXIS) == 1.0)); + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + public void start() { + String text = "aaa"; + f = new JFrame("bug4329185"); + JEditorPane jep = new JEditorPane(); + jep.setEditorKit(new MyHTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + f.getContentPane().add(jep); + f.setSize(500, 500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + + static class MyHTMLEditorKit extends HTMLEditorKit { + + private final ViewFactory defaultFactory = new MyHTMLFactory(); + + @Override + public ViewFactory getViewFactory() { + return defaultFactory; + } + + static class MyHTMLFactory extends HTMLEditorKit.HTMLFactory { + private int i = 0; + + @Override + public View create(Element elem) { + Object o = elem.getAttributes() + .getAttribute(StyleConstants.NameAttribute); + if (o instanceof HTML.Tag kind) { + if (kind == HTML.Tag.IMG) { + View v = super.create(elem); + views[i++] = v; + return v; + } + } + return super.create(elem); + } + } + } + +} diff -Nru openjdk-21-21.0.1+12/test/jdk/javax/swing/text/html/InlineView/bug4623342.java openjdk-21-21.0.2+13/test/jdk/javax/swing/text/html/InlineView/bug4623342.java --- openjdk-21-21.0.1+12/test/jdk/javax/swing/text/html/InlineView/bug4623342.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/javax/swing/text/html/InlineView/bug4623342.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,110 @@ +/* + * 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 4623342 + * @summary Tests if InlineView causes extra spacing around images in JTable + * @key headful + * @run main bug4623342 + */ + +import java.awt.Robot; +import java.awt.Shape; + +import javax.swing.JFrame; +import javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.text.View; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4623342 { + + private static volatile boolean passed; + + private JEditorPane jep; + private static JFrame f; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + bug4623342 test = new bug4623342(); + SwingUtilities.invokeAndWait(test::init); + robot.waitForIdle(); + robot.delay(100); + SwingUtilities.invokeAndWait(test::start); + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + public void init() { + + String text = + "" + + "" + + "
" + + "
" + + "
"; + + f = new JFrame(); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + f.getContentPane().add(jep); + f.setSize(500, 500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + private void start() { + Shape r = jep.getBounds(); + View v = jep.getUI().getRootView(jep); + int tableHeight = 0; + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + String viewName = v.getClass().getName(); + if (viewName.endsWith("TableView")) { + tableHeight = r.getBounds().height; + } + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + // tableHeight should be the sum of TD's heights (46) + passed = (tableHeight == 46); + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/jdk/internal/util/ArchTest.java openjdk-21-21.0.2+13/test/jdk/jdk/internal/util/ArchTest.java --- openjdk-21-21.0.1+12/test/jdk/jdk/internal/util/ArchTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/jdk/internal/util/ArchTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -20,23 +20,27 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +import java.nio.ByteOrder; +import java.util.List; import java.util.Locale; import java.util.stream.Stream; import jdk.internal.util.Architecture; import jdk.internal.misc.Unsafe; -import static jdk.internal.util.Architecture.OTHER; import static jdk.internal.util.Architecture.AARCH64; import static jdk.internal.util.Architecture.ARM; +import static jdk.internal.util.Architecture.LOONGARCH64; +import static jdk.internal.util.Architecture.MIPSEL; +import static jdk.internal.util.Architecture.MIPS64EL; +import static jdk.internal.util.Architecture.PPC; import static jdk.internal.util.Architecture.PPC64; +import static jdk.internal.util.Architecture.PPC64LE; import static jdk.internal.util.Architecture.RISCV64; -import static jdk.internal.util.Architecture.LOONGARCH64; import static jdk.internal.util.Architecture.S390; +import static jdk.internal.util.Architecture.SPARCV9; import static jdk.internal.util.Architecture.X64; import static jdk.internal.util.Architecture.X86; -import static jdk.internal.util.Architecture.MIPSEL; -import static jdk.internal.util.Architecture.MIPS64EL; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -44,20 +48,53 @@ import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; /** * @test - * @bug 8304915 + * @bug 8304915 8308452 8310982 * @summary Verify Architecture enum maps to system property os.arch * @modules java.base/jdk.internal.util * @modules java.base/jdk.internal.misc * @run junit ArchTest */ public class ArchTest { - private static boolean IS_BIG_ENDIAN = Unsafe.getUnsafe().isBigEndian(); + private static final boolean IS_BIG_ENDIAN = Unsafe.getUnsafe().isBigEndian(); + + private static final boolean IS_64BIT_ADDRESS = Unsafe.getUnsafe().addressSize() == 8; + + /** + * Test data for Architecture name vs Arch enums, address bits, endian-ness and boolean isXXX() methods.. + * Each Argument contains: + * - the common os.arch name, + * - the Architecture Enum, + * - address bits 32/64, + * - the byte-order (little or big), + * - the result of invoking the architecture specific static method + * @return a stream of arguments for parameterized tests + */ + private static Stream archParams() { + // In alphabetical order + return Stream.of( + Arguments.of("aarch64", AARCH64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isAARCH64()), + Arguments.of("amd64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64()), + Arguments.of("arm", ARM, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isARM()), + Arguments.of("i386", X86, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isX86()), + Arguments.of("loongarch64", LOONGARCH64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isLOONGARCH64()), + Arguments.of("mips64el", MIPS64EL, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isMIPS64EL()), + Arguments.of("mipsel", MIPSEL, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isMIPSEL()), + Arguments.of("ppc", PPC, 32, ByteOrder.BIG_ENDIAN, Architecture.isPPC()), + Arguments.of("ppc64", PPC64, 64, ByteOrder.BIG_ENDIAN, Architecture.isPPC64()), + Arguments.of("ppc64le", PPC64LE, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isPPC64LE()), + Arguments.of("riscv64", RISCV64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isRISCV64()), + Arguments.of("s390", S390, 64, ByteOrder.BIG_ENDIAN, Architecture.isS390()), + Arguments.of("s390x", S390, 64, ByteOrder.BIG_ENDIAN, Architecture.isS390()), + Arguments.of("sparcv9", SPARCV9, 64, ByteOrder.BIG_ENDIAN, Architecture.isSPARCV9()), + Arguments.of("x64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64()), + Arguments.of("x86", X86, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isX86()), + Arguments.of("x86_64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64()) + ); + } - private static boolean IS_64BIT_ADDRESS = Unsafe.getUnsafe().addressSize() == 8; /** * Test consistency of System property "os.arch" with Architecture.current(). @@ -65,46 +102,33 @@ @Test public void nameVsCurrent() { String osArch = System.getProperty("os.arch").toLowerCase(Locale.ROOT); - System.out.printf("System property os.arch: \"%s\", Architecture.current(): \"%s\"%n", + System.err.printf("System property os.arch: \"%s\", Architecture.current(): \"%s\"%n", osArch, Architecture.current()); - Architecture arch = switch (osArch) { - case "x86_64", "amd64" -> X64; - case "x86", "i386" -> X86; - case "aarch64" -> AARCH64; - case "arm" -> ARM; - case "riscv64" -> RISCV64; - case "loongarch64" -> LOONGARCH64; - case "s390x", "s390" -> S390; - case "ppc64", "ppc64le" -> PPC64; - case "mipsel" -> MIPSEL; - case "mips64el" -> MIPS64EL; - default -> OTHER; - }; - assertEquals(Architecture.current(), arch, "mismatch in Architecture.current vs " + osArch); - } - /** - * Test various Architecture enum values vs boolean isXXX() methods. - * @return a stream of arguments for parameterized test - */ - private static Stream archParams() { - return Stream.of( - Arguments.of(X64, Architecture.isX64()), - Arguments.of(X86, Architecture.isX86()), - Arguments.of(AARCH64, Architecture.isAARCH64()), - Arguments.of(ARM, Architecture.isARM()), - Arguments.of(RISCV64, Architecture.isRISCV64()), - Arguments.of(LOONGARCH64, Architecture.isLOONGARCH64()), - Arguments.of(S390, Architecture.isS390()), - Arguments.of(MIPSEL, Architecture.isMIPSEL()), - Arguments.of(MIPS64EL, Architecture.isMIPS64EL()), - Arguments.of(PPC64, Architecture.isPPC64()) - ); + // Map os.arch system property to expected Architecture + List argList = archParams() + .filter(p -> p.get()[0].equals(osArch)) + .map(a -> (Architecture)a.get()[1]) + .toList(); + assertEquals(1, argList.size(), osArch + " too few or too many matching system property os.arch cases: " + argList); + assertEquals(Architecture.current(), argList.get(0), "mismatch in Architecture.current vs " + osArch); } @ParameterizedTest @MethodSource("archParams") - public void isArch(Architecture arch, boolean isArch) { + public void checkParams(String archName, Architecture arch, int addrSize, ByteOrder byteOrder, boolean isArch) { + Architecture actual = Architecture.lookupByName(archName); + assertEquals(actual, arch, "Wrong Architecture from lookupByName"); + + actual = Architecture.lookupByName(archName.toUpperCase(Locale.ROOT)); + assertEquals(actual, arch, "Wrong Architecture from lookupByName (upper-case)"); + + actual = Architecture.lookupByName(archName.toLowerCase(Locale.ROOT)); + assertEquals(actual, arch, "Wrong Architecture from lookupByName (lower-case)"); + + assertEquals(addrSize, actual.addressSize(), "Wrong address size"); + assertEquals(byteOrder, actual.byteOrder(), "Wrong byteOrder"); + Architecture current = Architecture.current(); assertEquals(arch == current, isArch, "Method is" + arch + "(): returned " + isArch + ", should be (" + arch + " == " + current + ")"); diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - /* - * @test - * @bug 8189131 - * @summary Interoperability tests with Actalis CA - * @build ValidatePathWithParams - * @run main/othervm/timeout=180 -Djava.security.debug=certpath ActalisCA OCSP - * @run main/othervm/timeout=180 -Djava.security.debug=certpath ActalisCA CRL - */ - - /* - * Obtain test artifacts for Actalis CA from: - * - * Test website with *active* TLS Server certificate: - * https://ssltest-active.actalis.it/ - * - * Test website with *revoked* TLS Server certificate: - * https://ssltest-revoked.actalis.it/ - * - * Test website with *expired* TLS Server certificate: - * https://ssltest-expired.actalis.it/ - */ -public class ActalisCA { - - // Owner: CN=Actalis Organization Validated Server CA G3, O=Actalis S.p.A., - // L=Ponte San Pietro, ST=Bergamo, C=IT - // Issuer: CN=Actalis Authentication Root CA, O=Actalis S.p.A ./03358520967, - // L=Milan, C=IT - // Serial number: 5c3b3f37adfc28fe0fcfd3abf83f8551 - // Valid from: Mon Jul 06 00:20:55 PDT 2020 until: Sun Sep 22 04:22:02 PDT 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIHdTCCBV2gAwIBAgIQXDs/N638KP4Pz9Or+D+FUTANBgkqhkiG9w0BAQsFADBr\n" + - "MQswCQYDVQQGEwJJVDEOMAwGA1UEBwwFTWlsYW4xIzAhBgNVBAoMGkFjdGFsaXMg\n" + - "Uy5wLkEuLzAzMzU4NTIwOTY3MScwJQYDVQQDDB5BY3RhbGlzIEF1dGhlbnRpY2F0\n" + - "aW9uIFJvb3QgQ0EwHhcNMjAwNzA2MDcyMDU1WhcNMzAwOTIyMTEyMjAyWjCBiTEL\n" + - "MAkGA1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNh\n" + - "biBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMTQwMgYDVQQDDCtBY3Rh\n" + - "bGlzIE9yZ2FuaXphdGlvbiBWYWxpZGF0ZWQgU2VydmVyIENBIEczMIICIjANBgkq\n" + - "hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs73Ch+t2owm3ayTkyqy0OPuCTiybxTyS\n" + - "4cU4y0t2RGSwCNjLh/rcutO0yoriZxVtPrNMcIRQ544BQhHFt/ypW7e+t8wWKrHa\n" + - "r3BkKwSUbqNwpDWP1bXs7IJTVhHXWGAm7Ak1FhrrBmtXk8QtdzTzDDuxfFBK7sCL\n" + - "N0Jdqoqb1V1z3wsWqAvr4KlSCFW05Nh4baWm/kXOmb8U+XR6kUmuoVvia3iBhotR\n" + - "TzAHTO9SWWkgjTcir/nhBvyL2RoqkgYyP/k50bznaVOGFnFWzfl0XnrM/salfCBh\n" + - "O0/1vNaoU8elR6AtbdCFAupgQy95GuFIRVS8n/cF0QupfPjUl+kGSLzvGAc+6oNE\n" + - "alpAhKIS/+P0uODzRrS9Eq0WX1iSj6KHtQMNN4ZKsS4nsuvYCahnAc0QwQyoduAW\n" + - "iU/ynhU9WTIEe1VIoEDE79NPOI2/80RqbZqdpAKUaf0FvuqVXhEcjiJJu+d0w9YN\n" + - "b7gurd6xkaSXemW/fP4idBiNkd8aCVAdshGQYn6yh+na0Lu5IG88Z2kSIFcXDtwy\n" + - "zjcxkW86pwkO6GekEomVBNKcv0Cey2Smf8uhpZk15TSCeyFDrZBWH9OsDst/Tnhz\n" + - "pN156Huw3M3RRdEegt33fcyPykgt0HThxrEv9DwOzhs6lCQ5RNQJO7ZvZF1ZiqgT\n" + - "FOJ6vs1xMqECAwEAAaOCAfQwggHwMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgw\n" + - "FoAUUtiIOsifeGbtifN7OHCUyQICNtAwQQYIKwYBBQUHAQEENTAzMDEGCCsGAQUF\n" + - "BzABhiVodHRwOi8vb2NzcDA1LmFjdGFsaXMuaXQvVkEvQVVUSC1ST09UMEUGA1Ud\n" + - "IAQ+MDwwOgYEVR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hY3RhbGlz\n" + - "Lml0L2FyZWEtZG93bmxvYWQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB\n" + - "MIHjBgNVHR8EgdswgdgwgZaggZOggZCGgY1sZGFwOi8vbGRhcDA1LmFjdGFsaXMu\n" + - "aXQvY24lM2RBY3RhbGlzJTIwQXV0aGVudGljYXRpb24lMjBSb290JTIwQ0EsbyUz\n" + - "ZEFjdGFsaXMlMjBTLnAuQS4lMmYwMzM1ODUyMDk2NyxjJTNkSVQ/Y2VydGlmaWNh\n" + - "dGVSZXZvY2F0aW9uTGlzdDtiaW5hcnkwPaA7oDmGN2h0dHA6Ly9jcmwwNS5hY3Rh\n" + - "bGlzLml0L1JlcG9zaXRvcnkvQVVUSC1ST09UL2dldExhc3RDUkwwHQYDVR0OBBYE\n" + - "FJ+KsbXxsd6C9Cd8vojN3qlDgaNLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B\n" + - "AQsFAAOCAgEAJbygMnKJ5M6byr5Ectq05ODqwNMtky8TEF3O55g6RHhxblf6OegZ\n" + - "4ui4+ElHNOIXjycbeuUGuFA4LScCC9fnI1Rnn8TI2Q7OP5YWifEfnrdp99t/tJzQ\n" + - "hfdi7ZTdRRZZGV9x+grfR/RtjT2C3Lt9X4lcbuSxTea3PHAwwi0A3bYRR1L5ciPm\n" + - "eAnYtG9kpat8/RuC22oxiZZ5FdjU6wrRWkASRLiIwNcFIYfvpUbMWElaCUhqaB2y\n" + - "YvWF8o02pnaYb4bvTCg4cVabVnojUuuXH81LeQhhsSXLwcdwSdew0NL4zCiNCn2Q\n" + - "iDZpz2biCWDggibmWxsUUF6AbqMHnwsdS8vsKXiFQJHeAdNAhA+kwpqYAdhUiCdj\n" + - "RTUdtRNUucLvZEN1OAvVYyog9xYCfhtkqgXQROMANP+Z/+yaZahaP/Vgak/V00se\n" + - "Hdh7F+B6h5HVdwdh+17E2jl+aMTfyvBFcg2H/9Qjyl4TY8NW/6v0DPK52sVt8a35\n" + - "I+7xLGLPohAl4z6pEf2OxgjMNfXXCXS33smRgz1dLQFo8UpAb3rf84zkXaqEI6Qi\n" + - "2P+5pibVFQigRbn4RcE+K2a/nm2M/o+WZTSio+E+YXacnNk71VcO82biOof+jBKT\n" + - "iC3Xi7rAlypmme+QFBw9F1J89ig3smV/HaN8tO0lfTpvm7Zvzd5TkMs=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=ssltest-active.actalis.it, O=Actalis S.p.A., L=Ponte San Pietro, - // ST=Bergamo, C=IT - // Issuer: CN=Actalis Organization Validated Server CA G3, O=Actalis S.p A., - // L=Ponte San Pietro, ST=Bergamo, C=IT - // Serial number: 4a49e2afcd448af3b7f5f14e1cd5954 - // Valid from: Tue Mar 08 08:00:57 PST 2022 until: Wed Mar 08 08:00:57 PST 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIH0jCCBbqgAwIBAgIQBKSeKvzUSK87f18U4c1ZVDANBgkqhkiG9w0BAQsFADCB\n" + - "iTELMAkGA1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRl\n" + - "IFNhbiBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMTQwMgYDVQQDDCtB\n" + - "Y3RhbGlzIE9yZ2FuaXphdGlvbiBWYWxpZGF0ZWQgU2VydmVyIENBIEczMB4XDTIy\n" + - "MDMwODE2MDA1N1oXDTIzMDMwODE2MDA1N1owdzELMAkGA1UEBhMCSVQxEDAOBgNV\n" + - "BAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQaWV0cm8xFzAVBgNVBAoM\n" + - "DkFjdGFsaXMgUy5wLkEuMSIwIAYDVQQDDBlzc2x0ZXN0LWFjdGl2ZS5hY3RhbGlz\n" + - "Lml0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsJnlOatNNth7gfqZ\n" + - "WN8HMfp9qlkDf/YW8ReNXyTtqFEy2xZrVVmAV2XIqL1lJDYJz86mdVsz3AqIMTzo\n" + - "GxPlmn/oEnF0YeRYQ1coKRdwP7hWSwqyMMhh+C7r5zMA9gQQVXV5wWR5U+bgvt23\n" + - "Y/55DOqk3Fp5Odt6Lyu6xA45MwHrj2Gr/nMKe8L7f8UYPWT98MJa1+TXB24yllOw\n" + - "rZE8gZByLBCVzDkVwRwTgu+HgY6zm5sJTvBT4tyJy4QD8u2xLWoZ5sXodrU0Z3Nf\n" + - "xU9keMFp6CIh1t+akqFgpW81b/HWkfUO0+L6PH4hgaSPtiwp2dVFsF9v5p4on9qA\n" + - "2j1d9QIDAQABo4IDRTCCA0EwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSfirG1\n" + - "8bHegvQnfL6Izd6pQ4GjSzB+BggrBgEFBQcBAQRyMHAwOwYIKwYBBQUHMAKGL2h0\n" + - "dHA6Ly9jYWNlcnQuYWN0YWxpcy5pdC9jZXJ0cy9hY3RhbGlzLWF1dGhvdmczMDEG\n" + - "CCsGAQUFBzABhiVodHRwOi8vb2NzcDA5LmFjdGFsaXMuaXQvVkEvQVVUSE9WLUcz\n" + - "MCQGA1UdEQQdMBuCGXNzbHRlc3QtYWN0aXZlLmFjdGFsaXMuaXQwUQYDVR0gBEow\n" + - "SDA8BgYrgR8BFAEwMjAwBggrBgEFBQcCARYkaHR0cHM6Ly93d3cuYWN0YWxpcy5p\n" + - "dC9hcmVhLWRvd25sb2FkMAgGBmeBDAECAjAdBgNVHSUEFjAUBggrBgEFBQcDAgYI\n" + - "KwYBBQUHAwEwSAYDVR0fBEEwPzA9oDugOYY3aHR0cDovL2NybDA5LmFjdGFsaXMu\n" + - "aXQvUmVwb3NpdG9yeS9BVVRIT1YtRzMvZ2V0TGFzdENSTDAdBgNVHQ4EFgQUIbcm\n" + - "54DVM6gC8DYhvnZg8ILaLrAwDgYDVR0PAQH/BAQDAgWgMIIBfQYKKwYBBAHWeQIE\n" + - "AgSCAW0EggFpAWcAdQCt9776fP8QyIudPZwePhhqtGcpXc+xDCTKhYY069yCigAA\n" + - "AX9qTFEkAAAEAwBGMEQCIFB4RW+Fca/jj96sFg9JtZVe/CAQq74HAezTi2AD07qL\n" + - "AiBej8APns5uKmaHNYbU6lel6kdowIaUY/+iqX82e2KhrAB2AOg+0No+9QY1MudX\n" + - "KLyJa8kD08vREWvs62nhd31tBr1uAAABf2pMUVMAAAQDAEcwRQIgcopYpSUDiQ2C\n" + - "7j06vgbfsn3ux4REvpbrbWatifLtfVMCIQCi96i+4EhAUOw4dumA7hJwlG+qD/+5\n" + - "uSL3aKB9KR7apAB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAAB\n" + - "f2pMUYEAAAQDAEcwRQIgdCNjaV7nQcCiVefX28u1vtQMy+rqT4F4i9EVJ2xbqbQC\n" + - "IQCrpcYqt53tX/rSMoGnjFhDGnMhnYyc2AqzpokfhmdcVTANBgkqhkiG9w0BAQsF\n" + - "AAOCAgEAfXISBKP1dZQv1kkWZVDXiVY/fv+068DKq2e8hgBcsN6b9a2rlVfBU2iq\n" + - "W9KqFNET5GDWf1wjM71Itjau8b1A3+apcNdEGQk3eqIOymK5kVtVvAI2ahp4926x\n" + - "Kkt/sexmi1pJGA+eLfTixkCoaESh5P8U7HDW/vUFXm2AtLQih+oT5OVoYt5e9pXr\n" + - "hr8oadm/ZDJxiyDL1vcTIsl2TM4/Fpo2IWxYzUC+YshnuLiRwWI840maJmWFx/lJ\n" + - "Pzdik3P51Uef7VsCSBhTxER09/B4IrEUMDAhVgG5QNbcFSHvnmpV8JLrNuBKUROU\n" + - "xnDsWieKlb5YO6S6PjGOncOrd+k4RCIYRaekSnx52WBKkpqxMEv/rjY1Glx4Cota\n" + - "mpNiYDvZHGzrRQtY2eH17XhFatBxEEbJMA+0QPbFksHcKxAxJgMDncqag4TDq5fT\n" + - "I2NUxqiB51F5w0x+++lyLnUZ+z4BJFZ73VdtfoJ2fsuRhemOoZjHPi/V2exXpAfb\n" + - "pomha3KCrTcuFv1lj8mPx5L4ciNPxuDFgjeXEaTGjS8IvdNoJIrgdHdahMwkwS/y\n" + - "wei7FJ1Ey0maqRUpUlAY6sIQPQ/KDltTuKX/C94C5pYLI0JXCScr5xg6C+r2ckbA\n" + - "rjhpn3C/NptVyZgT8bL4XT5ITrAjwPciBj0yxYzUkrLZO1wKQSQ=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=ssltest-revoked.actalis.it, O=Actalis S.p.A., L=Ponte San Pietro, ST=Bergamo, C=IT - // Issuer: CN=Actalis Organization Validated Server CA G3, O=Actalis S.p.A., - // L=Ponte San Pietro, ST=Bergamo, C=IT - // Serial number: 320955171b78d49507508910da2c5bc4 - // Valid from: Tue Sep 27 03:40:43 PDT 2022 until: Wed Sep 27 03:40:43 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIH1TCCBb2gAwIBAgIQMglVFxt41JUHUIkQ2ixbxDANBgkqhkiG9w0BAQsFADCB\n" + - "iTELMAkGA1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRl\n" + - "IFNhbiBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMTQwMgYDVQQDDCtB\n" + - "Y3RhbGlzIE9yZ2FuaXphdGlvbiBWYWxpZGF0ZWQgU2VydmVyIENBIEczMB4XDTIy\n" + - "MDkyNzEwNDA0M1oXDTIzMDkyNzEwNDA0M1oweDELMAkGA1UEBhMCSVQxEDAOBgNV\n" + - "BAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQaWV0cm8xFzAVBgNVBAoM\n" + - "DkFjdGFsaXMgUy5wLkEuMSMwIQYDVQQDDBpzc2x0ZXN0LXJldm9rZWQuYWN0YWxp\n" + - "cy5pdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdBnbeFtw/Ejp1U\n" + - "gr86BQ5rqgGXWWXb7fsOhPb5On9RXTojg6oaeIV4GxHsMZhEDKQdcZ6JWAo2dbtp\n" + - "/7ereFEDWG/YJahLHFZ/ihXG4AmfObYEhoGbKitW75fOs/aWC7Veck/sXsw7cjLW\n" + - "GY623ybcF9DBExg3S4uLRaSkv5hXUDu/CzphUgwiEd5YNBZjcryOiS8+Y5EQ+2q+\n" + - "g+tdRG9m5G5YxeHWgQz2HDDwLDsJhWkb8/RsUurU/I+avHPhYk13K5Ysf311gww8\n" + - "bAsplfdJ2gdn8Is+EAEH4GJHqMybC95YDh1w5dY7dk/lIoNX4hYUIQimirIr3OW8\n" + - "Svkj1G8CAwEAAaOCA0cwggNDMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUn4qx\n" + - "tfGx3oL0J3y+iM3eqUOBo0swfgYIKwYBBQUHAQEEcjBwMDsGCCsGAQUFBzAChi9o\n" + - "dHRwOi8vY2FjZXJ0LmFjdGFsaXMuaXQvY2VydHMvYWN0YWxpcy1hdXRob3ZnMzAx\n" + - "BggrBgEFBQcwAYYlaHR0cDovL29jc3AwOS5hY3RhbGlzLml0L1ZBL0FVVEhPVi1H\n" + - "MzAlBgNVHREEHjAcghpzc2x0ZXN0LXJldm9rZWQuYWN0YWxpcy5pdDBRBgNVHSAE\n" + - "SjBIMDwGBiuBHwEUATAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hY3RhbGlz\n" + - "Lml0L2FyZWEtZG93bmxvYWQwCAYGZ4EMAQICMB0GA1UdJQQWMBQGCCsGAQUFBwMC\n" + - "BggrBgEFBQcDATBIBgNVHR8EQTA/MD2gO6A5hjdodHRwOi8vY3JsMDkuYWN0YWxp\n" + - "cy5pdC9SZXBvc2l0b3J5L0FVVEhPVi1HMy9nZXRMYXN0Q1JMMB0GA1UdDgQWBBS6\n" + - "o8qJpg3ixoyA2QBayptaTfc+5DAOBgNVHQ8BAf8EBAMCBaAwggF+BgorBgEEAdZ5\n" + - "AgQCBIIBbgSCAWoBaAB2AK33vvp8/xDIi509nB4+GGq0Zyldz7EMJMqFhjTr3IKK\n" + - "AAABg36SGRYAAAQDAEcwRQIgDXxSCQGfcIYroxNiDJg08IX38Y9+r5CC6T4NeW14\n" + - "FzgCIQDdEhEYsGIWpwyrnTLr4RFB5CMEq+84dByNT07UYkiVwwB2AHoyjFTYty22\n" + - "IOo44FIe6YQWcDIThU070ivBOlejUutSAAABg36SGTUAAAQDAEcwRQIgL2ig9RrM\n" + - "FPWESGRYGJJJYRHdcayHev66jawrf98saN8CIQD/CInlI3Vo7SBzzN/4uykjYsFZ\n" + - "u9RypT6AYv6AHPlNdQB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kT\n" + - "AAABg36SGU0AAAQDAEcwRQIhAOCD/dOs4HjyC+GQaQRh4U+/mUwWyu+CnlHdebmD\n" + - "hAvFAiAvBE0rbxgm8TpZLG2TaMk3dqZj7Q6FFdLlqTsvwhKa3jANBgkqhkiG9w0B\n" + - "AQsFAAOCAgEAEnPALMVp1pySJgHhugLWAUgiD6stpDWCKfaBxPr+jf34A5wS+m5r\n" + - "2VhYyNQpOwIQB76K2RSJQrdpg7Dg2L6EiUnbbClSTrOkZ4XX5ggBIjldDEx4ZxhI\n" + - "zwSw4KB6+DDAVMwsCL0q0E7AAPOMaZ0RDLteusqQYIYm08TXfJPWD8LjQPt/8Uie\n" + - "LOqm1eLUuwJc+eHFWV+Xr8Uea6SFwqNEj7qPHb2MElctET/MhSIIUKI1ObmrFwyB\n" + - "ElKEPaUh9L0HXpnuD8IWc7tw2mdvnWJhuGG8G6JkasTGvtZ4gKIDBdTrJcuj7MCS\n" + - "amz3ZBCY47tP1ohgImjqwg4ITYjX6UQXgj/nBVDdu+nXkEhx16uPJkTYWaun9Nio\n" + - "8RjYIOxXmDD39QbGUElP0Epsr2wcVT9tIFYMGzUpIO51mCk3Aq1AmiQZwZZhqOIN\n" + - "RDx7lGESPj3IgdVfJi9Ing/OUNtS46Ug9DSuDcGqdY7KnTYEUdWGsUJNtnpjd4lS\n" + - "U6oIAeW1aKuOve6iNg1vsFAN57aJNh1ih3BOup58J9ve42bNlAYWN8wiNxM+Aeba\n" + - "ArUSTnH/QEYCyMRD0XqIREVR9VhNODgSZbL3XedYBAW9wImi1whp+u+8aReXd7lC\n" + - "Q3kD9KRyfZ9Kk05Glf3DsZMWvp1N2ZZWaU2Ms5U3ijUheCiBrqrs8a8=\n" + - "-----END CERTIFICATE-----"; - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Tue Sep 27 03:52:40 PDT 2022", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,613 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 8233223 - * @summary Interoperability tests with Amazon's CA1, CA2, CA3, and CA4 - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath AmazonCA OCSP - * @run main/othervm -Djava.security.debug=certpath AmazonCA CRL - */ - -/* - * Obtain TLS test artifacts for Amazon CAs from: - * - * Amazon Root CA 1 - * Valid - https://good.sca1a.amazontrust.com/ - * Revoked - https://revoked.sca1a.amazontrust.com/ - * Amazon Root CA 2 - * Valid - https://good.sca2a.amazontrust.com/ - * Revoked - https://revoked.sca2a.amazontrust.com/ - * Amazon Root CA 3 - * Valid - https://good.sca3a.amazontrust.com/ - * Revoked - https://revoked.sca3a.amazontrust.com/ - * Amazon Root CA 4 - * Valid - https://good.sca4a.amazontrust.com/ - * Revoked - https://revoked.sca4a.amazontrust.com/ - */ -public class AmazonCA { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - new AmazonCA_1().runTest(pathValidator); - new AmazonCA_2().runTest(pathValidator); - new AmazonCA_3().runTest(pathValidator); - new AmazonCA_4().runTest(pathValidator); - } -} - -class AmazonCA_1 { - - // Owner: CN=Amazon RSA 2048 M02, O=Amazon, C=US - // Issuer: CN=Amazon Root CA 1, O=Amazon, C=US - // Serial number: 773124a4bcbd44ec7b53beaf194842d3a0fa1 - // Valid from: Tue Aug 23 15:25:30 PDT 2022 until: Fri Aug 23 15:25:30 PDT 2030 - private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIEXjCCA0agAwIBAgITB3MSSkvL1E7HtTvq8ZSELToPoTANBgkqhkiG9w0BAQsF\n" + - "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + - "b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjUzMFoXDTMwMDgyMzIyMjUzMFowPDEL\n" + - "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\n" + - "QSAyMDQ4IE0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtDGMZa\n" + - "qHneKei1by6+pUPPLljTB143Si6VpEWPc6mSkFhZb/6qrkZyoHlQLbDYnI2D7hD0\n" + - "sdzEqfnuAjIsuXQLG3A8TvX6V3oFNBFVe8NlLJHvBseKY88saLwufxkZVwk74g4n\n" + - "WlNMXzla9Y5F3wwRHwMVH443xGz6UtGSZSqQ94eFx5X7Tlqt8whi8qCaKdZ5rNak\n" + - "+r9nUThOeClqFd4oXych//Rc7Y0eX1KNWHYSI1Nk31mYgiK3JvH063g+K9tHA63Z\n" + - "eTgKgndlh+WI+zv7i44HepRZjA1FYwYZ9Vv/9UkC5Yz8/yU65fgjaE+wVHM4e/Yy\n" + - "C2osrPWE7gJ+dXMCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\n" + - "VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV\n" + - "HQ4EFgQUwDFSzVpQw4J8dHHOy+mc+XrrguIwHwYDVR0jBBgwFoAUhBjMhTTsvAyU\n" + - "lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v\n" + - "b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov\n" + - "L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E\n" + - "ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv\n" + - "b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB\n" + - "AQAtTi6Fs0Azfi+iwm7jrz+CSxHH+uHl7Law3MQSXVtR8RV53PtR6r/6gNpqlzdo\n" + - "Zq4FKbADi1v9Bun8RY8D51uedRfjsbeodizeBB8nXmeyD33Ep7VATj4ozcd31YFV\n" + - "fgRhvTSxNrrTlNpWkUk0m3BMPv8sg381HhA6uEYokE5q9uws/3YkKqRiEz3TsaWm\n" + - "JqIRZhMbgAfp7O7FUwFIb7UIspogZSKxPIWJpxiPo3TcBambbVtQOcNRWz5qCQdD\n" + - "slI2yayq0n2TXoHyNCLEH8rpsJRVILFsg0jc7BaFrMnF462+ajSehgj12IidNeRN\n" + - "4zl+EoNaWdpnWndvSpAEkq2P\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=Amazon RSA 2048 M01, O=Amazon, C=US - // Issuer: CN=Amazon Root CA 1, O=Amazon, C=US - // Serial number: 77312380b9d6688a33b1ed9bf9ccda68e0e0f - // Valid from: Tue Aug 23 15:21:28 PDT 2022 until: Fri Aug 23 15:21:28 PDT 2030 - private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIEXjCCA0agAwIBAgITB3MSOAudZoijOx7Zv5zNpo4ODzANBgkqhkiG9w0BAQsF\n" + - "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + - "b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjEyOFoXDTMwMDgyMzIyMjEyOFowPDEL\n" + - "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\n" + - "QSAyMDQ4IE0wMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOtxLKnL\n" + - "H4gokjIwr4pXD3i3NyWVVYesZ1yX0yLI2qIUZ2t88Gfa4gMqs1YSXca1R/lnCKeT\n" + - "epWSGA+0+fkQNpp/L4C2T7oTTsddUx7g3ZYzByDTlrwS5HRQQqEFE3O1T5tEJP4t\n" + - "f+28IoXsNiEzl3UGzicYgtzj2cWCB41eJgEmJmcf2T8TzzK6a614ZPyq/w4CPAff\n" + - "nAV4coz96nW3AyiE2uhuB4zQUIXvgVSycW7sbWLvj5TDXunEpNCRwC4kkZjK7rol\n" + - "jtT2cbb7W2s4Bkg3R42G3PLqBvt2N32e/0JOTViCk8/iccJ4sXqrS1uUN4iB5Nmv\n" + - "JK74csVl+0u0UecCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\n" + - "VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV\n" + - "HQ4EFgQUgbgOY4qJEhjl+js7UJWf5uWQE4UwHwYDVR0jBBgwFoAUhBjMhTTsvAyU\n" + - "lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v\n" + - "b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov\n" + - "L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E\n" + - "ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv\n" + - "b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB\n" + - "AQCtAN4CBSMuBjJitGuxlBbkEUDeK/pZwTXv4KqPK0G50fOHOQAd8j21p0cMBgbG\n" + - "kfMHVwLU7b0XwZCav0h1ogdPMN1KakK1DT0VwA/+hFvGPJnMV1Kx2G4S1ZaSk0uU\n" + - "5QfoiYIIano01J5k4T2HapKQmmOhS/iPtuo00wW+IMLeBuKMn3OLn005hcrOGTad\n" + - "hcmeyfhQP7Z+iKHvyoQGi1C0ClymHETx/chhQGDyYSWqB/THwnN15AwLQo0E5V9E\n" + - "SJlbe4mBlqeInUsNYugExNf+tOiybcrswBy8OFsd34XOW3rjSUtsuafd9AWySa3h\n" + - "xRRrwszrzX/WWGm6wyB+f7C4\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=valid.rootca1.demo.amazontrust.com - // Issuer: CN=Amazon RSA 2048 M02, O=Amazon, C=US - // Serial number: 60c6e837b2e7586d8464eb34f4a85fe - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIGKDCCBRCgAwIBAgIQBgxug3sudYbYRk6zT0qF/jANBgkqhkiG9w0BAQsFADA8\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + - "UlNBIDIwNDggTTAyMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLTEr\n" + - "MCkGA1UEAxMidmFsaWQucm9vdGNhMS5kZW1vLmFtYXpvbnRydXN0LmNvbTCCASIw\n" + - "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3hA+omhUcO8nYO8/+dkpbYz8WI\n" + - "1ms7Y7JA2pPFfp2N/aWcf6m5ORm1BkyGLOttjTu318Qpa9eahQ1Pi3RNe3BtqjD9\n" + - "jcHncpwAFMsXy1beZA7sZ7AA4vKltA3t6yrU5ruTLUGQwUndeIBBSTW5QpdT9I/p\n" + - "EM7d+Miwre63kofbJ1lVPAJvN/udMVqGWNF8V5qscklUUHoSKA3FWWsiCyIgnthg\n" + - "G3u6R1KH66Qionp0ho/ttvrBCI0C/bdrdH+wybFv8oFFvAW2U9xn2Azt47/2kHHm\n" + - "tTRjrgufhDbcz/MLR6hwBXAJuwVvJZmSqe7B4IILFexu6wjxZfyqVm2FMr8CAwEA\n" + - "AaOCAzMwggMvMB8GA1UdIwQYMBaAFMAxUs1aUMOCfHRxzsvpnPl664LiMB0GA1Ud\n" + - "DgQWBBSkrnsTnjwYhDRAeLy/9FXm/7hApDBlBgNVHREEXjBcgiJ2YWxpZC5yb290\n" + - "Y2ExLmRlbW8uYW1hem9udHJ1c3QuY29tghpnb29kLnNjYTBhLmFtYXpvbnRydXN0\n" + - "LmNvbYIaZ29vZC5zY2ExYS5hbWF6b250cnVzdC5jb20wDgYDVR0PAQH/BAQDAgWg\n" + - "MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAs\n" + - "hipodHRwOi8vY3JsLnIybTAyLmFtYXpvbnRydXN0LmNvbS9yMm0wMi5jcmwwEwYD\n" + - "VR0gBAwwCjAIBgZngQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFo\n" + - "dHRwOi8vb2NzcC5yMm0wMi5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0\n" + - "dHA6Ly9jcnQucjJtMDIuYW1hem9udHJ1c3QuY29tL3IybTAyLmNlcjAMBgNVHRMB\n" + - "Af8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVct520\n" + - "zROiModGfLzs3sNRSFlGcR+1mwAAAYgHvXWVAAAEAwBHMEUCICAs74qT1f9ufSr5\n" + - "PgQqtQFiXBbmbb3i4xwVV78USU5NAiEA/iJEfnTG+hZZaHYv2wVbg6tUY8fQgIhI\n" + - "2rbl6PrD9FIAdgBIsONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiEcwAAAYgH\n" + - "vXWWAAAEAwBHMEUCIQDf2nWyee/5+vSgk/O8P0BFvXYu89cyAugZHyd919BdAgIg\n" + - "UnGGpQtZmWnPMmdgpzI7jrCLuC370Tn0i7Aktdzj2X8AdgDatr9rP7W2Ip+bwrtc\n" + - "a+hwkXFsu1GEhTS9pD0wSNf7qwAAAYgHvXVpAAAEAwBHMEUCIGN6cT+6uwDospXe\n" + - "gMa8b38oXouXUT66X2gOiJ0SoRyQAiEAjDMu2vEll5tRpUvU8cD4gR2xV4hqoDxx\n" + - "Q+QGW+PvJxcwDQYJKoZIhvcNAQELBQADggEBACtxC3LlQvULeI3lt7ZYFSWndEhm\n" + - "tNUotoeKSXJXdoIpqSr10bzMPX9SHvemgOUtzP3JNqWPHw1uW9YFyeDE6yWj/B13\n" + - "Xj1hv1cqYIwyaOZBerU/9PT5PaCn20AC9DHbc7iBv+zs+DYiqlAFJ1GVaprwLul4\n" + - "8wp3gnC3Hjb8NykydCo6vw0AJ2UzjpjiTyVZ93jITzLOiboOUa1gQGnojzWlYaet\n" + - "sXe+RDylBp/Wuj1ZS7v/etltzYm5GanPi4y/p7Ta3Uky6std/GM6XbPRdBEFboFR\n" + - "B2IP0divd9c74Q+tLgpsAz5yXm9LtYPMcEPC2YRN2PgBg67c5+A7eIOluuw=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.rootca1.demo.amazontrust.com - // Issuer: CN=Amazon RSA 2048 M01, O=Amazon, C=US - // Serial number: e1023665b1268d788cc25bf69a9d05e - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGMjCCBRqgAwIBAgIQDhAjZlsSaNeIzCW/aanQXjANBgkqhkiG9w0BAQsFADA8\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + - "UlNBIDIwNDggTTAxMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLzEt\n" + - "MCsGA1UEAxMkcmV2b2tlZC5yb290Y2ExLmRlbW8uYW1hem9udHJ1c3QuY29tMIIB\n" + - "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxSPd1PWACxZohFCAJT1JWuXK\n" + - "GY29wZZ9yY0zoiq6+qYiUIU0crktytUNNI1ZpW/3qXpEw2ZQkM6WF1LshXtwGwrA\n" + - "zJwSeX1L9T5rOKhoBvoFeqfX7xu4VBM1/fDGt5X+NRFfD9Op9UfK5OsnL05TYach\n" + - "rdnfOA5wKGvMgFiN5CeOD0AtumXSuAnTZC85ojJTHjPF+hqV893WvrrUxLyyxtvh\n" + - "lq/WttFOjhfQu2IkfyDAFiH939uzUi0WSTAdsbsHuko5mDTDnOfMRbaaWZu0At01\n" + - "EgaIPeK+kGdi7EYwVndIwTKLeQ4mjIM8aj8Heg/y2hZ0kOmfCUZdUmJFlNoCIQID\n" + - "AQABo4IDOzCCAzcwHwYDVR0jBBgwFoAUgbgOY4qJEhjl+js7UJWf5uWQE4UwHQYD\n" + - "VR0OBBYEFMeBhIOkuWUY4DYqFrfgbD2eUeFtMG0GA1UdEQRmMGSCJHJldm9rZWQu\n" + - "cm9vdGNhMS5kZW1vLmFtYXpvbnRydXN0LmNvbYIdcmV2b2tlZC5zY2EwYS5hbWF6\n" + - "b250cnVzdC5jb22CHXJldm9rZWQuc2NhMWEuYW1hem9udHJ1c3QuY29tMA4GA1Ud\n" + - "DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0f\n" + - "BDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0wMS5hbWF6b250cnVzdC5jb20vcjJt\n" + - "MDEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggr\n" + - "BgEFBQcwAYYhaHR0cDovL29jc3AucjJtMDEuYW1hem9udHJ1c3QuY29tMDYGCCsG\n" + - "AQUFBzAChipodHRwOi8vY3J0LnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5j\n" + - "ZXIwDAYDVR0TAQH/BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA7s3Q\n" + - "ZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZsAAAGIB72TggAABAMARzBFAiAZ\n" + - "naLbRHRuaRrE304GSuWX/79MU/e+SSlr0cNJ0kNNaAIhAPnz9HayL4txhkTEZiMs\n" + - "nttNnNqD17I0J17JLVOF4i/4AHYASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/\n" + - "qznYhHMAAAGIB72TmwAABAMARzBFAiEAgEqT7CYGQ/u36/3YcxBH78QfknI9kgcY\n" + - "sgJLkurUF6cCIFZZ/b803+ek6o+bmdV/uVx2UlskAyyolZ2okBAb6IscAHYA2ra/\n" + - "az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGIB72TbQAABAMARzBFAiEA\n" + - "6z2RSoK263hvYF71rj1d0TpC70/6zagSRR4glHOT6IACICYvaMAnrCNSTSiZ20Wz\n" + - "Ju5roTippO3BWKhQYrTKZuu4MA0GCSqGSIb3DQEBCwUAA4IBAQB4S1JGulFpMIaP\n" + - "NtLUJmjWz8eexQdWLDVF+H8dd6xpZgpiYtig/Ynphzuk1IIF8DkT3CeK/9vrezgI\n" + - "igNjneN9B4eIuzi/rJzIKeUwpZ2k5D+36Ab4esseoc+TopmNerw8hidt2g818jER\n" + - "D71ppSMakeQFPGe/Hs2/cVa/G1DNVcU2XAut45yRZ/+xsZ0/mcBDVsG9P5uGCN5O\n" + - "7SAp4J959WnKDqgVuU9WowPE5IjmS9BAv2gjniFYdDV2yksyf7+8edHd1KfSVX06\n" + - "pLx6CuCVZGJFG4Q2Aa1YAh1Wvt9hqWeXXpNRO2/wChL5rhT4GajsrGepsk4bjxYX\n" + - "Wf2iZ8mX\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - - // Validate valid - pathValidator.validate(new String[]{VALID, INT_VALID}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, - ValidatePathWithParams.Status.REVOKED, - "Mon May 15 13:36:57 PDT 2023", System.out); - } -} - -class AmazonCA_2 { - - // Owner: CN=Amazon RSA 4096 M02, O=Amazon, C=US - // Issuer: CN=Amazon Root CA 2, O=Amazon, C=US - // Serial number: 773125b0c34c3c940299a9f04a39e5a52ccd9 - // Valid from: Tue Aug 23 15:29:13 PDT 2022 until: Fri Aug 23 15:29:13 PDT 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIGXjCCBEagAwIBAgITB3MSWww0w8lAKZqfBKOeWlLM2TANBgkqhkiG9w0BAQwF\n" + - "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + - "b24gUm9vdCBDQSAyMB4XDTIyMDgyMzIyMjkxM1oXDTMwMDgyMzIyMjkxM1owPDEL\n" + - "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\n" + - "QSA0MDk2IE0wMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMGMl/pZ\n" + - "1OsxHY9gw/YfdON4mmrANkPwi7z2djHA5ELt/vRI3Su0le6OoipLf03iyoCnYy4Y\n" + - "rpfTbhyDriE8NJpps2ODJ5W1h0rz6FM1Q5Jt35wfk+4CEfATBTegHVlUJ0rJgzK5\n" + - "Yl/jrk12ZsC4ZeRn54shszcK6bHj4LZIHXhrYIIfetBMMD8V7hlhd54AclEWutUV\n" + - "eBEjkSCzDSk+pQKIjCL0crqvRSPvUNry/BV65zfGmceSYxpcLmV7k7Spwpo+1z8w\n" + - "+Odfnx2vsm7olPldfaThqk6fXBtInORl4Ef32xF3VDT13UeXtQPolFhnp8UOci64\n" + - "bW+R8tbtGpUXIA8Dhr8SgYPH6NW4jhUD4+AG8yer8ctA1Hl9tq+6tYr26q3yuCLu\n" + - "5rwJdfMG634fWIRXSj+GJi8SfAdGtPyXwu5799NWesV4vUkrkSXdIBK4TQCuK+jx\n" + - "aJ5Y+Zo2l3GFsWyMPNORLjoQXbjF6KAyjTyICLq9VzoQKhyx4Ll2CNrQv8CxqtDC\n" + - "GvXi9kREJYAF6lscOB0xglAAF5lndcaNkVHEVOMdg9ZZtdJywHWm8Qed1Wty2qr+\n" + - "hmA7booWQNRE12nW1niC5D4cP2ykPK9HSgb7xWdUF32VidUc9tNKM6xKjSd/R/tP\n" + - "p+XAybNSwEooPt3/OvyhpVRjLuWoqqbClTKdAgMBAAGjggFaMIIBVjASBgNVHRMB\n" + - "Af8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcD\n" + - "AQYIKwYBBQUHAwIwHQYDVR0OBBYEFJ5xHxodk6nZLY7MSFM/A1TznuZmMB8GA1Ud\n" + - "IwQYMBaAFLAM8Eww9AVYAkj9M+VSr0uE42ZSMHsGCCsGAQUFBwEBBG8wbTAvBggr\n" + - "BgEFBQcwAYYjaHR0cDovL29jc3Aucm9vdGNhMi5hbWF6b250cnVzdC5jb20wOgYI\n" + - "KwYBBQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhMi5hbWF6b250cnVzdC5jb20vcm9v\n" + - "dGNhMi5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2EyLmFt\n" + - "YXpvbnRydXN0LmNvbS9yb290Y2EyLmNybDATBgNVHSAEDDAKMAgGBmeBDAECATAN\n" + - "BgkqhkiG9w0BAQwFAAOCAgEAl1GgKXOn0j1MWT1KJVSewQ28SGbie3UwZj1dMsjJ\n" + - "amCrQPn2ngSNbLm9+ulFiBDU8xKR9Zx3tZps55IUKWLUPkfMC+vkV7asDBqqzzE0\n" + - "F/MkekgPfOjx1V9S6Wfg3sSg+9KcluurXFElruqKfOm4cqmkV776X1G+AaaQ7mlU\n" + - "giCYi6NqRQSyhn8zrKkNnbO6QL5a9ICC47kiZYRAR/hRvZOt11QUK5tCMXJXo0iO\n" + - "4XKkMu+jdnehP1kh4xuZhYznIgKK6MJIITFI/Jj89U4SOPncyuS94sUuE2EqvvO/\n" + - "t81qeoey6wThz5iRbU/0CvDFnTMgebWGUZ2UZJ+az/rb3KYXGfVWasLIonkvYT7z\n" + - "vHOGNAA9oQ8TTgPOmPfSVyfpplKtO/aybWp5QSH2csIwuvw5dkmpkc42iD57XHob\n" + - "5LbMJg99z3vQBmod/ipmOpND95/BeA2mllBZgZ53S0nvDXDzbzR9Fd81PAz9Qruo\n" + - "dOJKcD6plKQjZjkLzNh1v/RoCFO8kiJGE4UBMTM8FUk0DXH4bALII4wwmDelrSUu\n" + - "lKvDTDxZvPF4dbEXICNPd51EMGPgETxwboOV+bzWFVI0IWQ8PhZ2VuMPDk2taOMp\n" + - "NsuLtlYc2twPb9r/Hvgv7G6+ItpBHZwOVt1oI3pHbjMp7P3pOZSPr6G1WkNy9mX8\n" + - "rVc=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=valid.rootca2.demo.amazontrust.com - // Issuer: CN=Amazon RSA 4096 M02, O=Amazon, C=US - // Serial number: 662f7646d76193cbb76946d111e49fa - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIICzCCBfOgAwIBAgIQBmL3ZG12GTy7dpRtER5J+jANBgkqhkiG9w0BAQwFADA8\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + - "UlNBIDQwOTYgTTAyMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLTEr\n" + - "MCkGA1UEAxMidmFsaWQucm9vdGNhMi5kZW1vLmFtYXpvbnRydXN0LmNvbTCCAiIw\n" + - "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAON5EbEKoBiujI7Ja8mLZLJbaY7f\n" + - "RtoWIjU/F0l9ueWFogXmEaA1jWsl97F3WTHTyGKz6ChCjPMSyoXXpY+yoE90QUyX\n" + - "w35uWEhNrc40drMJkyN+QXitSrH346GCOKvpYVvu18UD4W8hDhg8vvbOQYhtmSf7\n" + - "Rfrs7/qUdXpzpvR9VjWktbQAzJT8fB/jFNjNQJTknynjGiYO5GF51+peOCLK6qw8\n" + - "9kKYEigR4K8/aWL283rC4xRxZqVioy433VG02l/Fwdv8o/vL9YYIqkyspCB9fpFw\n" + - "Q50yYrwEomxuOz7rXhmdfeNaFYuyTtOUSKff6p2oqO0S7pcLujUVMlO4dYBDELQF\n" + - "cabByNjwblviCtGKJMIzD6Thkgamp3iXQgcU498+P5r7N5CYbMmkJEdcuILg+bgJ\n" + - "/LUUTT+IMt2txYlO/ld3N0EHlgVt7rztW5mtm6Ba8jN7cLSh7ZWu6Fr1+oK7bl5T\n" + - "wPxSfqT5W3BwQKS3YptIoKEWUb+VNnS/dYx/7IspF9+z6kw4g+V2EY9M4ZYNakzM\n" + - "AI7KIj4thMFoWeYrJq0dUMZ297QCBPRdAwh9hhkq2LYi2x8tMUtcBnhb/q75sO+E\n" + - "icPqFVv7iMDZ/8Xep+0UoClF3JGmZW3UNtwcbi7Pn/OqtaMi7E8xnHUgc4ZchtXO\n" + - "v8VtVvDeZAlY5TjVAgMBAAGjggMWMIIDEjAfBgNVHSMEGDAWgBSecR8aHZOp2S2O\n" + - "zEhTPwNU857mZjAdBgNVHQ4EFgQUnGekBRKIZBYgCEajbpCMC24bp2owSQYDVR0R\n" + - "BEIwQIIidmFsaWQucm9vdGNhMi5kZW1vLmFtYXpvbnRydXN0LmNvbYIaZ29vZC5z\n" + - "Y2EyYS5hbWF6b250cnVzdC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG\n" + - "CCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3Js\n" + - "LnI0bTAyLmFtYXpvbnRydXN0LmNvbS9yNG0wMi5jcmwwEwYDVR0gBAwwCjAIBgZn\n" + - "gQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5y\n" + - "NG0wMi5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQucjRt\n" + - "MDIuYW1hem9udHJ1c3QuY29tL3I0bTAyLmNlcjAMBgNVHRMBAf8EAjAAMIIBfQYK\n" + - "KwYBBAHWeQIEAgSCAW0EggFpAWcAdgDuzdBk1dsazsVct520zROiModGfLzs3sNR\n" + - "SFlGcR+1mwAAAYgHvX9QAAAEAwBHMEUCIQD8qPPCLL2Grd+/YNALWqAq7LC7YBaa\n" + - "dNg5+6Q4kRDEqgIgEkf/UMsMNfTRaOZvoOgAK9/F0xX/CfdcUTjULhmoA+cAdQBI\n" + - "sONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiEcwAAAYgHvX8UAAAEAwBGMEQC\n" + - "IBVFDtapMMWJOqyu8Cv6XEhFmbU8N33c2owed//pa80xAiAT9T6Wba3B9DFUmrL5\n" + - "cCGKLqciIEUPhPbvjCuUepelrAB2ANq2v2s/tbYin5vCu1xr6HCRcWy7UYSFNL2k\n" + - "PTBI1/urAAABiAe9ft8AAAQDAEcwRQIhAP2XDC/RlmVtH4WrfSwVosR/f/WXRhG5\n" + - "mk9Nwq+ZOIriAiAopPXSH7VwXa3bEAIiTwcV1l10QIDZaIPCU5olknU5CjANBgkq\n" + - "hkiG9w0BAQwFAAOCAgEAFuwMIJdP5rgz6cqOIj2EgF2OU8CUGi/wJ45BomXWv4Rv\n" + - "U5mOKB+jHOGZZC9dncjAMa44RwoF2I7/8Y3qLVaoNm46ObvvS+6UvzTcyQqXM7JU\n" + - "cSmdlf9DkspjKPDvMBokVrM4ak5AoxUjuru5qaia3nvbxq7XKO9/FGUaUaU8Xlsd\n" + - "V6Fo8VmNwFc88VCqOp8eI/IicHxMDLl8TKXMvr3CYh8A9nCeFGcV+4CL+7JF2t5K\n" + - "YvV5r074Wyk0QMlRVYMNDl0t+VAEoDJ7RRE+kEvplWcsX9S2wvr4HhkA4iChpwFm\n" + - "2UDTppHskSWyLsuNQvipn0zTzZ8RIxXd/ei0qCdhKmkV7x9cgbTiyXgaI7iJEtdo\n" + - "RvYNcXc2RmitWjY5Av8yJGOk0eYpCwRrBv6ughbtJe3NMrqUeTyrKidIEo9KnRSA\n" + - "rMokRbHunkroS97VkoK/9j9pNJki+qAH9XTLYWcm/5+cTSGRsN+escRgZwV6KWg/\n" + - "JQQe5LbwU2HHzNqWuk63GC/ngVlWXjaVFfbNVmYEKZFFazcZchesN1YyDu+WndOx\n" + - "+rTcuke2feOvQ4EnVviM0k85JZNiqPDH2iafAWyqZFUYTnb7XK3HhJflAniv/SLq\n" + - "DQfbJmtQtNHdJYgVmC1u2RT9gbJDIAj0ZI4vU2WVB5Hmd9F31un6jundEuG4+S4=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.rootca2.demo.amazontrust.com - // Issuer: CN=Amazon RSA 4096 M02, O=Amazon, C=US - // Serial number: 788baa8f47bc5b1c624424216240fd3 - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIIEjCCBfqgAwIBAgIQB4i6qPR7xbHGJEJCFiQP0zANBgkqhkiG9w0BAQwFADA8\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + - "UlNBIDQwOTYgTTAyMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLzEt\n" + - "MCsGA1UEAxMkcmV2b2tlZC5yb290Y2EyLmRlbW8uYW1hem9udHJ1c3QuY29tMIIC\n" + - "IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzJfddWdrWhA9dSJdmy23veN9\n" + - "oLvSqpM4YaXGZmPtKUmbFMLs2I3vCKrzflRKeOpl3MCc2hh6TH/3z+Q/fGugXLsY\n" + - "H8QcjSbiIOd15n+3dUFTLKaoWMyseMcWiOIVaN5rCDVXiAHdt1pc147wyFQIzqNK\n" + - "J/xiV1u9eT2MFue+4bd7kUNAcmI8M+SXruhto4jtAV8ugpTEChTDlyO/l8xmaM1Q\n" + - "HkijsHX7Aq72Q/3PH/U+wbJ9pmpTp4x2AEJoo45IGfB/NKDTrv5otLBuiP8Y0M7b\n" + - "K7irRPDFBqMNZw7S7p39SnC+V/WibJQk5Bo/8vcwDJX+WnDkw1QD/uXu3ugDzSDD\n" + - "iBDViMOdN+3K47s4x2kdssoh4WWScMlAVb4vyN7IA3J4TnwA/1uCWhw4LE1WvY7N\n" + - "etekhVP1eWF8IzNY0oo2u2ie79777xvBtmtp7RnvYLGv7I+xVhjH5qGNzn9fRCUm\n" + - "QDego5HAfJ0PLlMEagdW8asCak1WaC117adnibL6WPtFA2FD2i6gNalTvhXhK2Ex\n" + - "alGxrVd/BCseT3bMp783jqScJO1g6xRHu0Qx+RyrOGVvcKZa6Y0DcAc8psRpkHaO\n" + - "HZY+lE8O2CIxpAJlwSnD6BoDNo8sg1IqFNkECw3wqfeMPBcg38k6zjAxwRDcIx6U\n" + - "SwDl4d3sjrmy3gOFFXMCAwEAAaOCAxswggMXMB8GA1UdIwQYMBaAFJ5xHxodk6nZ\n" + - "LY7MSFM/A1TznuZmMB0GA1UdDgQWBBQXpWT7gMHO+HKoHM1gU1VQVnylRzBOBgNV\n" + - "HREERzBFgiRyZXZva2VkLnJvb3RjYTIuZGVtby5hbWF6b250cnVzdC5jb22CHXJl\n" + - "dm9rZWQuc2NhMmEuYW1hem9udHJ1c3QuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNV\n" + - "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0\n" + - "cDovL2NybC5yNG0wMi5hbWF6b250cnVzdC5jb20vcjRtMDIuY3JsMBMGA1UdIAQM\n" + - "MAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDov\n" + - "L29jc3AucjRtMDIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8v\n" + - "Y3J0LnI0bTAyLmFtYXpvbnRydXN0LmNvbS9yNG0wMi5jZXIwDAYDVR0TAQH/BAIw\n" + - "ADCCAX0GCisGAQQB1nkCBAIEggFtBIIBaQFnAHYA7s3QZNXbGs7FXLedtM0TojKH\n" + - "Rny87N7DUUhZRnEftZsAAAGIB72CzgAABAMARzBFAiEA2vPYIPfGJeynPaZHq/c0\n" + - "GGvyT6MpvFGMW0s0woLRT28CIEFbZbFSCnKugaqw9QDNi7vYmIF3Gyi3s6G2cCxY\n" + - "4RJXAHYASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGIB72DDgAA\n" + - "BAMARzBFAiAvfNcgtFEwk5C9dvMUYANbIAv0IOdF1new8Umn3cM+JwIhALbs/3L9\n" + - "0ndF7sRKDZmfronNruptFlrI528P5Qi2P528AHUA2ra/az+1tiKfm8K7XGvocJFx\n" + - "bLtRhIU0vaQ9MEjX+6sAAAGIB72CxQAABAMARjBEAiBKUns2FPbs0cThb6e7SnyL\n" + - "y4/qP3V1Q/ASt/ZDRTeEQQIgWSQO4Gsz32srtqYuTM9AsFd92WA44kJHincdcGVX\n" + - "XbIwDQYJKoZIhvcNAQEMBQADggIBAAnaNbn2wXylTCS7dtgB3rWdUf6hja1UDuvB\n" + - "uZEL2dUOvyXfVFLNxKdeWBPzqpwEBNNwPQXhoI97TXlyu2x60jLzQamoGoRQ3s0P\n" + - "NLhasLGEIQH/oYdMV/yp8EI8fUuRVE3xyw39FRqOrmsUFAnxNQmBO/09JM7sLcvS\n" + - "wwh14p9dFTTolJHgnL4ZEtmZxSddFG+GBSTJ/A7dVSmwIudwzd+goA6173BI6yeT\n" + - "hhQumLctQiOM7y1MzFeV8rL+oIpd2xuzyhKKT1EgvU6/wyt0Ib8QqsFsrXPnUOKk\n" + - "HAq3SeZyq35QUaTKoaH9L1iZMbSCG9Jm6FMb12SdAz53653tYvAiUS76oD8Jot13\n" + - "RZu5NUlWAVLLq0OaEtuGp0bh+cVtzVnCC9m1qa46YpY0SojpvSbakgQMMGIgDlT3\n" + - "wFE7tST4WlsDC1f/m+H9V5qz/j0U8D3eNNdowxPqx/JZq/sk9ZK5KyMFARrvM+fh\n" + - "YrVYjKt91mu7JaS4pPOyZmJ8OQ14EvrN7BXc7IkNrI1reeaRFe49k5DAETB8VmP5\n" + - "2F0SWou2KkgtJvU4Z7YjlZ2HNHnpjTK5KdPNpRSt7EUy2zn9NCNoyQhnws70FyXv\n" + - "oPFyG92lnUQOKaAUhVRwTr9fvnkdMOzSKg/spxi2Ogdzym5Jw68eguwi0dVqX2+9\n" + - "3zViP2aH\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon May 15 13:38:54 PDT 2023", System.out); - } -} - -class AmazonCA_3 { - - // Owner: CN=Amazon ECDSA 256 M02, O=Amazon, C=US - // Issuer: CN=Amazon Root CA 3, O=Amazon, C=US - // Serial number: 773126de2c2fafd2c47ad88b1566e0182046d - // Valid from: Tue Aug 23 15:33:24 PDT 2022 until: Fri Aug 23 15:33:24 PDT 2030 - private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIC1DCCAnmgAwIBAgITB3MSbeLC+v0sR62IsVZuAYIEbTAKBggqhkjOPQQDAjA5\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + - "Um9vdCBDQSAzMB4XDTIyMDgyMzIyMzMyNFoXDTMwMDgyMzIyMzMyNFowPTELMAkG\n" + - "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEdMBsGA1UEAxMUQW1hem9uIEVDRFNB\n" + - "IDI1NiBNMDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS9vQLD4W/Kg4AnFRl8\n" + - "x/FUbLqtd5ICYjUijGsytF9hmgb/Dyk+Ebt4cw6rAlGbaiOLapSJKZiZr+UQdh3I\n" + - "QOr+o4IBWjCCAVYwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYw\n" + - "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBS7eJrXaDMy\n" + - "nRq7bP2xNEwB3svQdTAfBgNVHSMEGDAWgBSrttvXBp43rDCGB5Fwx5zEGbF4wDB7\n" + - "BggrBgEFBQcBAQRvMG0wLwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLnJvb3RjYTMu\n" + - "YW1hem9udHJ1c3QuY29tMDoGCCsGAQUFBzAChi5odHRwOi8vY3J0LnJvb3RjYTMu\n" + - "YW1hem9udHJ1c3QuY29tL3Jvb3RjYTMuY2VyMD8GA1UdHwQ4MDYwNKAyoDCGLmh0\n" + - "dHA6Ly9jcmwucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNhMy5jcmwwEwYD\n" + - "VR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwIDSQAwRgIhAKSYEcDcp3kcPMzh\n" + - "OIYDWZOLu4InPod4fQhRTmc2zBAgAiEAmwdGE4AuNWhw9N8REhf82rJLNm7h9Myg\n" + - "TsR9Wu0bQYU=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=Amazon ECDSA 256 M01, O=Amazon, C=US - // Issuer: CN=Amazon Root CA 3, O=Amazon, C=US - // Serial number: 773126684d577c0fcf8d3a342bea86f94fc8f - // Valid from: Tue Aug 23 15:31:46 PDT 2022 until: Fri Aug 23 15:31:46 PDT 2030 - private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIC0zCCAnmgAwIBAgITB3MSZoTVd8D8+NOjQr6ob5T8jzAKBggqhkjOPQQDAjA5\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + - "Um9vdCBDQSAzMB4XDTIyMDgyMzIyMzE0NloXDTMwMDgyMzIyMzE0NlowPTELMAkG\n" + - "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEdMBsGA1UEAxMUQW1hem9uIEVDRFNB\n" + - "IDI1NiBNMDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT80w+2RwNHzyXmVUM/\n" + - "OUKBZpJkTzHyCKDl4sBrUfjzVjot/lNba9kYzMKSHYv95CUDoMaF2h2KAqx65uLQ\n" + - "Y8ago4IBWjCCAVYwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYw\n" + - "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBRPWfy8BhYo\n" + - "v6LI2wj7zxMkumlCXDAfBgNVHSMEGDAWgBSrttvXBp43rDCGB5Fwx5zEGbF4wDB7\n" + - "BggrBgEFBQcBAQRvMG0wLwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLnJvb3RjYTMu\n" + - "YW1hem9udHJ1c3QuY29tMDoGCCsGAQUFBzAChi5odHRwOi8vY3J0LnJvb3RjYTMu\n" + - "YW1hem9udHJ1c3QuY29tL3Jvb3RjYTMuY2VyMD8GA1UdHwQ4MDYwNKAyoDCGLmh0\n" + - "dHA6Ly9jcmwucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNhMy5jcmwwEwYD\n" + - "VR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwIDSAAwRQIhALRfxq3SQIhj5xA4\n" + - "S5UAY/KlKqayZDpnbBdCDH8Kqmf/AiAUVZddALefnqRe+ifxN2FUp461LL6/cgVM\n" + - "EH3Ty27f1Q==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=valid.rootca3.demo.amazontrust.com - // Issuer: CN=Amazon ECDSA 256 M02, O=Amazon, C=US - // Serial number: 8e2f14864fb28e4a1da0f15a5118cc8 - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIEfjCCBCWgAwIBAgIQCOLxSGT7KOSh2g8VpRGMyDAKBggqhkjOPQQDAjA9MQsw\n" + - "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + - "U0EgMjU2IE0wMjAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC0xKzAp\n" + - "BgNVBAMTInZhbGlkLnJvb3RjYTMuZGVtby5hbWF6b250cnVzdC5jb20wWTATBgcq\n" + - "hkjOPQIBBggqhkjOPQMBBwNCAAQfWc7gBGBBBmseCb2XWWRQVhCUQDVml3mVgvj5\n" + - "RmnP1y5wpifUTFqu8ELdI7YGZ4JMSnetiKNmLtg5yhTEjzCQo4IDFTCCAxEwHwYD\n" + - "VR0jBBgwFoAUu3ia12gzMp0au2z9sTRMAd7L0HUwHQYDVR0OBBYEFHCE8orvZDUK\n" + - "5TI9MYadzxWR9CZGMEkGA1UdEQRCMECCInZhbGlkLnJvb3RjYTMuZGVtby5hbWF6\n" + - "b250cnVzdC5jb22CGmdvb2Quc2NhM2EuYW1hem9udHJ1c3QuY29tMA4GA1UdDwEB\n" + - "/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQw\n" + - "MjAwoC6gLIYqaHR0cDovL2NybC5lMm0wMi5hbWF6b250cnVzdC5jb20vZTJtMDIu\n" + - "Y3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEF\n" + - "BQcwAYYhaHR0cDovL29jc3AuZTJtMDIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUF\n" + - "BzAChipodHRwOi8vY3J0LmUybTAyLmFtYXpvbnRydXN0LmNvbS9lMm0wMi5jZXIw\n" + - "DAYDVR0TAQH/BAIwADCCAXwGCisGAQQB1nkCBAIEggFsBIIBaAFmAHUA7s3QZNXb\n" + - "Gs7FXLedtM0TojKHRny87N7DUUhZRnEftZsAAAGIB71y/gAABAMARjBEAiAEAXIb\n" + - "aOVR26HgFaI+qoIasCb8w2sOqVxGAxf5iPgX6QIgdAlMjqeoihi1arnJpzN8Bqxy\n" + - "5ULMUO7GK3JEgcogJHMAdgBIsONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiE\n" + - "cwAAAYgHvXLkAAAEAwBHMEUCIF7wDDmWxTHwBZM7Me8eOCM1aQ/g1c1rJg/I+NJa\n" + - "HkZYAiEA8p+IviuY5piHBELjUtVlZLiS9XSSMxpQNhUerqC/YFoAdQDatr9rP7W2\n" + - "Ip+bwrtca+hwkXFsu1GEhTS9pD0wSNf7qwAAAYgHvXKvAAAEAwBGMEQCIFLskZDs\n" + - "UG4+/88D/5/QbD9zT6ZmZlwXiPZ6H2YR/KiJAiBvi4vvNsb9KNAhJMgI2T2iCg9U\n" + - "CIru+US6y3ua7dKKDTAKBggqhkjOPQQDAgNHADBEAiAzvgzKV/kvBbKWCT1NNUBD\n" + - "AF9okIEcJx/ukFgzmYMwUQIgXeJeVf3izkxsgiEUSknwHsErLFs/cEme2PSRj2AW\n" + - "dYA=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.rootca3.demo.amazontrust.com - // Issuer: CN=Amazon ECDSA 256 M01, O=Amazon, C=US - // Serial number: c458bfaeedae16a5e61fe64773fc898 - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIEhzCCBC2gAwIBAgIQDEWL+u7a4WpeYf5kdz/ImDAKBggqhkjOPQQDAjA9MQsw\n" + - "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + - "U0EgMjU2IE0wMTAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC8xLTAr\n" + - "BgNVBAMTJHJldm9rZWQucm9vdGNhMy5kZW1vLmFtYXpvbnRydXN0LmNvbTBZMBMG\n" + - "ByqGSM49AgEGCCqGSM49AwEHA0IABAsSs5kW5TZlS0SDrMb9iUQAqEaKa12Fc6SN\n" + - "9UR6qtOFdW/1UuziDq3Hl5dqsAYZJkbJSPCIsD2HTP/EGTMKITCjggMbMIIDFzAf\n" + - "BgNVHSMEGDAWgBRPWfy8BhYov6LI2wj7zxMkumlCXDAdBgNVHQ4EFgQUeE55ET2e\n" + - "i8KbY7KHTxOuvCkRpTowTgYDVR0RBEcwRYIkcmV2b2tlZC5yb290Y2EzLmRlbW8u\n" + - "YW1hem9udHJ1c3QuY29tgh1yZXZva2VkLnNjYTNhLmFtYXpvbnRydXN0LmNvbTAO\n" + - "BgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDsG\n" + - "A1UdHwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmwuZTJtMDEuYW1hem9udHJ1c3QuY29t\n" + - "L2UybTAxLmNybDATBgNVHSAEDDAKMAgGBmeBDAECATB1BggrBgEFBQcBAQRpMGcw\n" + - "LQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLmUybTAxLmFtYXpvbnRydXN0LmNvbTA2\n" + - "BggrBgEFBQcwAoYqaHR0cDovL2NydC5lMm0wMS5hbWF6b250cnVzdC5jb20vZTJt\n" + - "MDEuY2VyMAwGA1UdEwEB/wQCMAAwggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB2\n" + - "AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABiAe9lQ8AAAQDAEcw\n" + - "RQIgZVFAX5WPZRBpEOqk620v4Rbzxh/3wrJ5QBMBJ0Mb8B0CIQC0oxFVLfs+PAv7\n" + - "25wawOu2VgDXG9lJAJtCwk3gN8BshQB2AEiw42vapkc0D+VqAvqdMOscUgHLVt0s\n" + - "gdm7v6s52IRzAAABiAe9lQ4AAAQDAEcwRQIhAIPVMj6IfjAUKeGYbpG9s0DRdWbc\n" + - "b8OzsOf+kRqk03NMAiB777hfoFCUMPrN0g8o5v6zp3T3qOhRnYY0TZN4q4NnMgB1\n" + - "ANq2v2s/tbYin5vCu1xr6HCRcWy7UYSFNL2kPTBI1/urAAABiAe9lN4AAAQDAEYw\n" + - "RAIgL0qoVbKLFD+Y3f/V6Rw+euZrPO6d1HEVPQGo7wLzkl8CIGHp3PQmmrEofl76\n" + - "4da7bY0L+csFW0sB8clN0KziMfe6MAoGCCqGSM49BAMCA0gAMEUCIQC+6VdX9X5g\n" + - "x3NSUmJ7py01Zxf26TNBv1ildxqesvZ/7wIgIrefriRzPiIFDHCUbdjk0VlmMwZR\n" + - "VzXXHINsGCiCKOs=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - - // Validate valid - pathValidator.validate(new String[]{VALID, INT_VALID}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, - ValidatePathWithParams.Status.REVOKED, - "Mon May 15 13:41:22 PDT 2023", System.out); - } -} - -class AmazonCA_4 { - - // Owner: CN=Amazon ECDSA 384 M02, O=Amazon, C=US - // Issuer: CN=Amazon Root CA 4, O=Amazon, C=US - // Serial number: 773127dfaa6b9e2b95538aa76dde4307f17c4 - // Valid from: Tue Aug 23 15:36:58 PDT 2022 until: Fri Aug 23 15:36:58 PDT 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIDETCCApagAwIBAgITB3MSffqmueK5VTiqdt3kMH8XxDAKBggqhkjOPQQDAzA5\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + - "Um9vdCBDQSA0MB4XDTIyMDgyMzIyMzY1OFoXDTMwMDgyMzIyMzY1OFowPTELMAkG\n" + - "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEdMBsGA1UEAxMUQW1hem9uIEVDRFNB\n" + - "IDM4NCBNMDIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATNYzWQDXV0NoNmR0hJPwJq\n" + - "hjYOOS9z0B2Z7MQudxg5x3Vsib6N+tJkq8dljRq5o6K0bbh/kRVfoi9wfKhB03Yz\n" + - "gkerrwRCH7Z9gU5nbBY+Y5+EtImq4yOB0n7JQgQxWemjggFaMIIBVjASBgNVHRMB\n" + - "Af8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcD\n" + - "AQYIKwYBBQUHAwIwHQYDVR0OBBYEFKbZqzuHmTP/6Gj4i2GDbNCyuq+9MB8GA1Ud\n" + - "IwQYMBaAFNPsxzplbszh2naaVvuc84ZtV+WBMHsGCCsGAQUFBwEBBG8wbTAvBggr\n" + - "BgEFBQcwAYYjaHR0cDovL29jc3Aucm9vdGNhNC5hbWF6b250cnVzdC5jb20wOgYI\n" + - "KwYBBQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhNC5hbWF6b250cnVzdC5jb20vcm9v\n" + - "dGNhNC5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2E0LmFt\n" + - "YXpvbnRydXN0LmNvbS9yb290Y2E0LmNybDATBgNVHSAEDDAKMAgGBmeBDAECATAK\n" + - "BggqhkjOPQQDAwNpADBmAjEA2zCG6x0xMlgSXWEGLN8+1XN+OCYF5vj0Z1jtVy+A\n" + - "pdLlzuxNt9HBWn3hvqvO2W8KAjEApNdsZOCmk5uZBYiuCSBnDH3jyKhN6dWyuuHW\n" + - "9Wj7SxKnOU5+wYWZA0BQAv1KT62i\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=valid.rootca4.demo.amazontrust.com - // Issuer: CN=Amazon ECDSA 384 M02, O=Amazon, C=US - // Serial number: f579bed3369f1a147ea5d0e8e6532d3 - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIEvjCCBESgAwIBAgIQD1eb7TNp8aFH6l0OjmUy0zAKBggqhkjOPQQDAzA9MQsw\n" + - "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + - "U0EgMzg0IE0wMjAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC0xKzAp\n" + - "BgNVBAMTInZhbGlkLnJvb3RjYTQuZGVtby5hbWF6b250cnVzdC5jb20wdjAQBgcq\n" + - "hkjOPQIBBgUrgQQAIgNiAAT6/95JFuvx5t9MVeRZmBtXq63Q2fXZnSwEy2U2F4Qc\n" + - "ejhDwcYfD2HmT6S6GrKqLNJMa5n2YOvet4LZpKJLFF+BQo6FJt5cXkzHHxZ1I4z3\n" + - "8pGU79CpCgFOFy6QUlF68NajggMXMIIDEzAfBgNVHSMEGDAWgBSm2as7h5kz/+ho\n" + - "+Ithg2zQsrqvvTAdBgNVHQ4EFgQUR/GnpQkrUsCj8jF6/JIE1Rs07zswSQYDVR0R\n" + - "BEIwQIIidmFsaWQucm9vdGNhNC5kZW1vLmFtYXpvbnRydXN0LmNvbYIaZ29vZC5z\n" + - "Y2E0YS5hbWF6b250cnVzdC5jb20wDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQG\n" + - "CCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3Js\n" + - "LmUzbTAyLmFtYXpvbnRydXN0LmNvbS9lM20wMi5jcmwwEwYDVR0gBAwwCjAIBgZn\n" + - "gQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5l\n" + - "M20wMi5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuZTNt\n" + - "MDIuYW1hem9udHJ1c3QuY29tL2UzbTAyLmNlcjAMBgNVHRMBAf8EAjAAMIIBfgYK\n" + - "KwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVct520zROiModGfLzs3sNR\n" + - "SFlGcR+1mwAAAYgHvZA9AAAEAwBHMEUCIQCmzmQOzunsuAg1GpIcNx0isG6ylbhP\n" + - "y9JP4UFclL2hdwIgBtTM89mE7QJDj7h7xr2eRPio1ehgmeYH1PHXxCqHIGYAdgBI\n" + - "sONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiEcwAAAYgHvZB1AAAEAwBHMEUC\n" + - "IF9hbi82CLU5umfRze4NpX6u4jlT+N8KSaBe6UbhqjBZAiEAi2Y6PTt2+107LxtM\n" + - "oBpHprph7hQvGfjPE+p+rfM/X+EAdgDatr9rP7W2Ip+bwrtca+hwkXFsu1GEhTS9\n" + - "pD0wSNf7qwAAAYgHvZBeAAAEAwBHMEUCIAI+m4mVE3HtZOEMC5VI7m0nEPdPPJUq\n" + - "fxUKPpeIVmk5AiEA0scVJy7g3Fv+2nTVhbcwWCwn/Gvc+0txQrc529juflcwCgYI\n" + - "KoZIzj0EAwMDaAAwZQIxAKV837BpqlNHg35EsCCtrJPoQ6RuY9UoHm1O2CdsCXGR\n" + - "Z3kAnlgIV8A/waI6wQqfsQIwdCqaC+qN60JCnX09YKRD15eQjq1rN3w+llI+lEbS\n" + - "FSMsnoHJcqMZLo9s+4Rf0zS3\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.rootca4.demo.amazontrust.com - // Issuer: CN=Amazon ECDSA 384 M02, O=Amazon, C=US - // Serial number: 4a5d392936b4decb818b7fb106ebbd8 - // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIExjCCBEygAwIBAgIQBKXTkpNrTey4GLf7EG672DAKBggqhkjOPQQDAzA9MQsw\n" + - "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + - "U0EgMzg0IE0wMjAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC8xLTAr\n" + - "BgNVBAMTJHJldm9rZWQucm9vdGNhNC5kZW1vLmFtYXpvbnRydXN0LmNvbTB2MBAG\n" + - "ByqGSM49AgEGBSuBBAAiA2IABFYfMbv5/vgqDunZj4ffJiuELtdwfEPXx9QlZnCm\n" + - "rBP3Z4/GvUVRVmyh5sYdnbCGCEClH/RxU6BC5SKv+TzhsFLEumhezanljnQXRAIL\n" + - "a1OGbP8zLLP6FuAD0cjY3P3adKOCAx0wggMZMB8GA1UdIwQYMBaAFKbZqzuHmTP/\n" + - "6Gj4i2GDbNCyuq+9MB0GA1UdDgQWBBSqnGV5pN/agPCtVdV37CP1z/DUqjBOBgNV\n" + - "HREERzBFgiRyZXZva2VkLnJvb3RjYTQuZGVtby5hbWF6b250cnVzdC5jb22CHXJl\n" + - "dm9rZWQuc2NhNGEuYW1hem9udHJ1c3QuY29tMA4GA1UdDwEB/wQEAwIHgDAdBgNV\n" + - "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0\n" + - "cDovL2NybC5lM20wMi5hbWF6b250cnVzdC5jb20vZTNtMDIuY3JsMBMGA1UdIAQM\n" + - "MAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDov\n" + - "L29jc3AuZTNtMDIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8v\n" + - "Y3J0LmUzbTAyLmFtYXpvbnRydXN0LmNvbS9lM20wMi5jZXIwDAYDVR0TAQH/BAIw\n" + - "ADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYAdv+IPwq2+5VRwmHM9Ye6NLSk\n" + - "zbsp3GhCCp/mZ0xaOnQAAAGIB72QJQAABAMARzBFAiA74zKrlL+y5rYwSLxBL8fs\n" + - "QYRYXF0s0sGoaSEeAg1DkgIhAPu8Z0TLIFoppmyiv+A5z6S+SG+v/kOsAYmQmiUO\n" + - "5scIAHcASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGIB72QJgAA\n" + - "BAMASDBGAiEAg+x7JBT3oIaZdnfgGN1G6SAiNUL7zR/tBhbWIG9tz94CIQDGwBiV\n" + - "Tslt11+W3ZaNsS7UtUIiB45YHUc4qKm5ry2fTAB2ANq2v2s/tbYin5vCu1xr6HCR\n" + - "cWy7UYSFNL2kPTBI1/urAAABiAe9kAgAAAQDAEcwRQIgPvKfSpMJKRocGk9+GNr3\n" + - "hUj8x8WySB//0X116TNgA0gCIQDhGRqxnEZmEFGEfj5GY9vjEfm0kKwcL0lCuwBu\n" + - "NZG4dzAKBggqhkjOPQQDAwNoADBlAjEA1PLdsrko3tDs50aAeEU9Gn+0CG8QKy7R\n" + - "fQaXBTjGETDgGJk/7zGNpGelKPr/UYV9AjASwdA32S8jIADxA8HrqiMsVYDFMnbU\n" + - "jLLwR6CTLtAcWtwVmoQ2x0usvTvN8YJBPoA=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon May 15 13:42:48 PDT 2023", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2017, 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. - */ - - /* - * @test - * @bug 8189131 - * @summary Interoperability tests with Buypass Class 2 and Class 3 CA - * @build ValidatePathWithParams - * @run main/othervm/timeout=180 -Djava.security.debug=certpath BuypassCA OCSP - * @run main/othervm/timeout=180 -Djava.security.debug=certpath BuypassCA CRL - */ - - /* - * Obtain test artifacts for Buypass Class 2 and Class 3 CAs from: - * Buypass Class 3 CA 2 - * https://valid.qcevident.ca23.ssl.buypass.no/ - * https://revoked.qcevident.ca23.ssl.buypass.no/ - * https://expired.qcevident.ca23.ssl.buypass.no/ - * https://valid.evident.ca23.ssl.buypass.no/ - * https://revoked.evident.ca23.ssl.buypass.no/ - * https://expired.evident.ca23.ssl.buypass.no/ - * https://valid.businessplus.ca23.ssl.buypass.no - * https://revoked.businessplus.ca23.ssl.buypass.no - * https://expired.businessplus.ca23.ssl.buypass.no - - * Buypass Class 2 CA 2 - * https://valid.business.ca22.ssl.buypass.no - * https://revoked.business.ca22.ssl.buypass.no - * https://expired.business.ca22.ssl.buypass.no - * https://valid.domain.ca22.ssl.buypass.no - * https://revoked.domain.ca22.ssl.buypass.no - * https://expired.domain.ca22.ssl.buypass.no/ - */ -public class BuypassCA { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - new BuypassClass2().runTest(pathValidator); - new BuypassClass3().runTest(pathValidator); - } -} - -class BuypassClass2 { - - // Owner: CN=Buypass Class 2 CA 2, O=Buypass AS-983163327, C=NO - // Issuer: CN=Buypass Class 2 Root CA, O=Buypass AS-983163327, C=NO - // Serial number: 1b781c6d5e34ce1f77 - // Valid from: Mon Mar 25 05:17:10 PDT 2019 until: Sat Oct 26 02:16:17 PDT 2030 - private static final String INT_CLASS_2 = "-----BEGIN CERTIFICATE-----\n" + - "MIIFKTCCAxGgAwIBAgIJG3gcbV40zh93MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNV\n" + - "BAYTAk5PMR0wGwYDVQQKDBRCdXlwYXNzIEFTLTk4MzE2MzMyNzEgMB4GA1UEAwwX\n" + - "QnV5cGFzcyBDbGFzcyAyIFJvb3QgQ0EwHhcNMTkwMzI1MTIxNzEwWhcNMzAxMDI2\n" + - "MDkxNjE3WjBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMx\n" + - "NjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAyMIIBIjANBgkqhkiG\n" + - "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnKtnxpZLDQ+R0uzKzDMr83L8Dn+5ToSpD31z\n" + - "qiYMykj7I2geNQ7javKsBOzhgeVr7GP4yJ5bK/P0dhoKesYvQITihfwztbMP6DyH\n" + - "q1QJLQBqQnF0Lk8GhxSSNAZnlkCgX3aazoL32p9BeEfHuUE/8BlPywJY/RyE5/39\n" + - "w3EKmWylhUkeRCMo3dUZr4khJq8JwGp/feKFs9n5FouM5PGhpFpZO+WQXEeqxpnc\n" + - "CxbvWpInBoTnmX3+ofjm+fmY+sdAnyHkuOBBw3koGbFQygDaJP9VItOGByCX4iSV\n" + - "ty/2uzppowIkf7Mpu5v5HJGKObLMP1gGv5lNqjAe8mz0bn25kwIDAQABo4IBCzCC\n" + - "AQcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTJgHfgYpKC9Uac87r3TMPe\n" + - "uKOtOTAdBgNVHQ4EFgQUkq1libIAD8tRDcEj7JROj8EEP3cwDgYDVR0PAQH/BAQD\n" + - "AgEGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjARBgNVHSAECjAIMAYG\n" + - "BFUdIAAwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2NybC5idXlwYXNzLm5vL2Ny\n" + - "bC9CUENsYXNzMlJvb3RDQS5jcmwwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzAB\n" + - "hhdodHRwOi8vb2NzcC5idXlwYXNzLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEApNka\n" + - "48a+qhJXXS9R24p34CWnirlyxPMhxFfQyvPFXnwBQGHvrm7H5KY3/9/etShFXdY/\n" + - "N05Aq6UnE8my8jR4iHMm2e9iEf4v+O2E2JGH/5/H8wup160GBAsp4zAmJIT8KEgh\n" + - "YAA1j+NaClVryZfEaaDfAdF6LbU3cW0ZgooILPMeeCEXso23KsdCD1Q+SMvD6nQJ\n" + - "86iTvzWPY2GFJyEmvG/N2f29nBaHxWwZBwCfWB4Hqsw9wdKfY5M9SE/AGSLZ7LRM\n" + - "BmkkF9nqkWxxISadx12nbxn0LsU2k8Xyt830DqhHGSoYHEC/iGxbU4Bub8NC0uw/\n" + - "QNBj5Gd5cXLFhRUWLLBTq4p6P6kLc7JudpM4FNQ+stWK/eDZylbDLN3iCBRnHH4p\n" + - "qg6HAlWuieiAKVsidBMxPUyDLJ/8Dt+aW8Z3vCNcYC2n7wqrLZz5e4FG+Wn9teFW\n" + - "Rt5pO6ZUZAkDS59ZVojbbjOdQzNw3QHtZl0IMHeNYXJlPIUlHi4hGL3maGZ9sBF+\n" + - "AMfMLDu56+J2DewIuTXPzCeJeSTam/ybNt5FxTznxCSCIDqwmZMy3AQEz9nGSbE8\n" + - "zfwB5VT2ijLB0PpPX4YbLf33Vodf0NAkBUv6N5It30XiTUPhdk+caBYPoljz/J9U\n" + - "15T5+EGHs8ccHQWyYQ6gqYk8o4JgP4rSJqO1sMI=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=valid.domain.ca22.ssl.buypass.no - // Issuer: CN=Buypass Class 2 CA 2, O=Buypass AS-983163327, C=NO - // Serial number: 34e2bff8063debd18d79 - // Valid from: Mon Sep 23 04:12:34 PDT 2019 until: Mon Oct 11 14:59:00 PDT 2021 - private static final String VALID_CLASS_2 = "-----BEGIN CERTIFICATE-----\n" + - "MIIF8jCCBNqgAwIBAgIKNOK/+AY969GNeTANBgkqhkiG9w0BAQsFADBLMQswCQYD\n" + - "VQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMM\n" + - "FEJ1eXBhc3MgQ2xhc3MgMiBDQSAyMB4XDTE5MDkyMzExMTIzNFoXDTIxMTAxMTIx\n" + - "NTkwMFowKzEpMCcGA1UEAwwgdmFsaWQuZG9tYWluLmNhMjIuc3NsLmJ1eXBhc3Mu\n" + - "bm8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCeu/8j7y55R3OucDek\n" + - "gtdoVOEJQb2XaCR4OwiRzn74hLYhKGdFmFwSp+bPCT62NzjdK1urVeKrCQdC1Gkm\n" + - "e7iSOsHHO5aC8oxkgdv8mwEwwvH7xHCcpEVLDlE5Oc0d4cS4QIwFAhNIC77slixL\n" + - "fEdupc5e8FfQf3MlnhX+8gpgRzTx3iw8sb3gUwi3+7PRommHOhC7Ll+iI9LiLODJ\n" + - "qrkHnCbM2HJMK+SGTOQ/whiQwMCnkLaEG0WO1rYc4BGRGfFb8qmQWw/tDKkEey7X\n" + - "nLIFHSC33OiexQshAwRIAE7r1h9gMY1aAAB2Uxwi9/3l6fsd/VPmK7s7lYTBsrpK\n" + - "r4bTAgMBAAGjggL2MIIC8jAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFJKtZYmyAA/L\n" + - "UQ3BI+yUTo/BBD93MB0GA1UdDgQWBBSy+COaEmU2/BeF4g1OglFvAEYkIDAOBgNV\n" + - "HQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB8GA1Ud\n" + - "IAQYMBYwCgYIYIRCARoBAgQwCAYGZ4EMAQIBMDoGA1UdHwQzMDEwL6AtoCuGKWh0\n" + - "dHA6Ly9jcmwuYnV5cGFzcy5uby9jcmwvQlBDbGFzczJDQTIuY3JsMCsGA1UdEQQk\n" + - "MCKCIHZhbGlkLmRvbWFpbi5jYTIyLnNzbC5idXlwYXNzLm5vMGoGCCsGAQUFBwEB\n" + - "BF4wXDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuYnV5cGFzcy5jb20wNQYIKwYB\n" + - "BQUHMAKGKWh0dHA6Ly9jcnQuYnV5cGFzcy5uby9jcnQvQlBDbGFzczJDQTIuY2Vy\n" + - "MIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdwC72d+8H4pxtZOUI5eqkntHOFeV\n" + - "CqtS6BqQlmQ2jh7RhQAAAW1d0tivAAAEAwBIMEYCIQDFRAH98gYpvMMTVa3d5Wcq\n" + - "0tOwpZZyUHiOjUlR3SD14QIhAKZp0cdwFpm+hh0taFVSTmluGsHmXPMCIQq9hLAB\n" + - "VYgyAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFtXdLbFwAA\n" + - "BAMARzBFAiBhr7KQc9yO3zb1iLlE0JW9whR0/bhrPDkk5BYnBKjzFAIhAMMTdHfk\n" + - "1ljso5jKzIUcBpSW0HnTcuKiB3VxGpL7GFVWAHUAb1N2rDHwMRnYmQCkURX/dxUc\n" + - "EdkCwQApBo2yCJo32RMAAAFtXdLYSAAABAMARjBEAiADoZr6Cp5AGM1eT2aUeRaQ\n" + - "kv0vRaegjRGIhKRCvRGyFAIgWLU/7zh28LI8vAyWr8mpDqlUXvF13i3zSD3whq4L\n" + - "Lu4wDQYJKoZIhvcNAQELBQADggEBAJH1RhTuMbhEOYlw+Efbx7PP7EEC/GQ1ijET\n" + - "vZS45jFQyTKhFUcdP2QPAtEVo1nS8PBs0txQJBf0xceWUjer9ruxiAS+JlW21AOi\n" + - "Uq9Kahpj5k63Z7tN8KTeOUE8wZGmHyvVcPP6mkC94RbjYIb4gd13eYxd2Vv1a7YX\n" + - "dNI+J3g7sX5ijssfJxzDd0hORj2584YY2WiKKvIGxwDnLkxk09i3IvjEKsAi4Cgn\n" + - "5798X5sSL1Q9C6gHEWt+cB5UtfILCfbLNRczS9zGku6gjh1c8dB7zc63mn7oCf1C\n" + - "gnQ2xqwbZb3Wau8CPwcMqJWgQZLQFPbZd+4Xo5SDDqYppV4oN2A=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.domain.ca22.ssl.buypass.no - // Issuer: CN=Buypass Class 2 CA 2, O=Buypass AS-983163327, C=NO - // Serial number: 34e4b97261795f98c495 - // Valid from: Mon Sep 23 04:52:42 PDT 2019 until: Thu Sep 23 14:59:00 PDT 2021 - private static final String REVOKED_CLASS_2 = "-----BEGIN CERTIFICATE-----\n" + - "MIIF9zCCBN+gAwIBAgIKNOS5cmF5X5jElTANBgkqhkiG9w0BAQsFADBLMQswCQYD\n" + - "VQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMM\n" + - "FEJ1eXBhc3MgQ2xhc3MgMiBDQSAyMB4XDTE5MDkyMzExNTI0MloXDTIxMDkyMzIx\n" + - "NTkwMFowLTErMCkGA1UEAwwicmV2b2tlZC5kb21haW4uY2EyMi5zc2wuYnV5cGFz\n" + - "cy5ubzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOiChajGbQktGjbl\n" + - "k/i5PtqfMN6cMyjJdOirxzXdUG8dT+QErC5zcElCwuyy5MH7DQJRbSYsPxQmr6z5\n" + - "OSheBxX0lPPLjJFfEafBZ+Fw1xmCVy3Xjt3GEl85iqv5y0/E/UlQPc0f7s6WxU0L\n" + - "cItkyN0rWAa+uQY018qDFn+gDYIKWPzTCf5nkXIgob/IgBM1Bj7vSZ/LI1iB+I+G\n" + - "dgLbSGBlJgK6lhCTc1tunZlSbKdPM2Th8Hbl6Uk7WormR/8SrGQA9AAd7BWa43V5\n" + - "HHvf/oArsx0afp3zXNiMw9RgHVHI5uUAzkNnL8NMUpI1sK7/ndTlm0nXsHpPKrPo\n" + - "e+NpKaMCAwEAAaOCAvkwggL1MAkGA1UdEwQCMAAwHwYDVR0jBBgwFoAUkq1libIA\n" + - "D8tRDcEj7JROj8EEP3cwHQYDVR0OBBYEFDoBaIahoDhRhA3WVyT/XukqZzmAMA4G\n" + - "A1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYD\n" + - "VR0gBBgwFjAKBghghEIBGgECBDAIBgZngQwBAgEwOgYDVR0fBDMwMTAvoC2gK4Yp\n" + - "aHR0cDovL2NybC5idXlwYXNzLm5vL2NybC9CUENsYXNzMkNBMi5jcmwwLQYDVR0R\n" + - "BCYwJIIicmV2b2tlZC5kb21haW4uY2EyMi5zc2wuYnV5cGFzcy5ubzBqBggrBgEF\n" + - "BQcBAQReMFwwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmJ1eXBhc3MuY29tMDUG\n" + - "CCsGAQUFBzAChilodHRwOi8vY3J0LmJ1eXBhc3Mubm8vY3J0L0JQQ2xhc3MyQ0Ey\n" + - "LmNlcjCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYAu9nfvB+KcbWTlCOXqpJ7\n" + - "RzhXlQqrUugakJZkNo4e0YUAAAFtXfeApgAABAMARzBFAiARoEDgK57YWEW2R21d\n" + - "jFMphF5c9PypIwbZFHiWxdyCyAIhALsjjtPGgcrT/7KebYFPuKDyQO6rc8YYvm0z\n" + - "Q+Xt7NhxAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFtXfeD\n" + - "eQAABAMARzBFAiBCXKlCGkqa85QVqMR5dYDDz3F5aQgLXPubrQLX7cAZ0wIhALRr\n" + - "p8F6OfIdccSUhzEcNdtensQ/7zxgn81bUzn1ar9EAHcAb1N2rDHwMRnYmQCkURX/\n" + - "dxUcEdkCwQApBo2yCJo32RMAAAFtXfeBSQAABAMASDBGAiEAyrR31T85HGekHZdD\n" + - "r/m6flxqQaUIGcAJ5WcrBuIBuYkCIQD0rDdm+vM5/lNXIfjjrPLhATFEvrxpXJvu\n" + - "+sW4Ntm94jANBgkqhkiG9w0BAQsFAAOCAQEAjbMEFeNXFy3YQSr8O0+fY7qwaAzk\n" + - "vq65Ef/B2zvqO375+JI21grUikmFUnDiAaM8Y+8PJkOXDiuxR2/XCLsXpxCcPqQh\n" + - "V0MZlqXtjKZjBACILBX7aqGibojJTIlo0Dkd+LfPwswfXscTbb1CUXpUPn7CiUj5\n" + - "0WwfvjjQXny0NAB6WEkBMEBx6/Q75dvltoV9N1BZVer9hov6UTDuSad86faX2QF2\n" + - "aIEjrTJY3m2HqnIYf/lQxuDUDW0h7ddGGsIEBDM8z7M/rvT068ssRqJ8uecGjMaz\n" + - "JElX8VDgMux2kyjTAiAFD5QO+KTfySri9QXptik3wo66zDOmkVES1snvVQ==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID_CLASS_2, INT_CLASS_2}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED_CLASS_2, INT_CLASS_2}, - ValidatePathWithParams.Status.REVOKED, - "Mon Sep 23 04:53:18 PDT 2019", System.out); - } -} - -class BuypassClass3 { - - // Owner: CN=Buypass Class 3 CA 2, O=Buypass AS-983163327, C=NO - // Issuer: CN=Buypass Class 3 Root CA, O=Buypass AS-983163327, C=NO - // Serial number: 1be0dc6a3e7f220475 - // Valid from: Mon Mar 25 05:12:16 PDT 2019 until: Sat Oct 26 01:16:17 PDT 2030 - private static final String INT_CLASS_3 = "-----BEGIN CERTIFICATE-----\n" + - "MIIFKTCCAxGgAwIBAgIJG+Dcaj5/IgR1MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNV\n" + - "BAYTAk5PMR0wGwYDVQQKDBRCdXlwYXNzIEFTLTk4MzE2MzMyNzEgMB4GA1UEAwwX\n" + - "QnV5cGFzcyBDbGFzcyAzIFJvb3QgQ0EwHhcNMTkwMzI1MTIxMjE2WhcNMzAxMDI2\n" + - "MDgxNjE3WjBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMx\n" + - "NjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAyMIIBIjANBgkqhkiG\n" + - "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvU4V2hRFFe4K7BMEmm4IoMTwS7NyDQB4JEar\n" + - "dV1qBsKHIIQJDm9hbCakcLIWXVv6vYrJZ1AEF0b6awBwhhlqXlyNnOtNa9uR+IAP\n" + - "86d4yOGpgHSlNAhdtOOk9Qw6MUzzBo1lyoYmoL0f5n02SMrlMcArSg458o08eDUx\n" + - "4iZs4dXDR9Hjxac2s+mdAO35Js8VK/D50AIMDJvHVeCMw+rumZkNZuRqM7PjIK+u\n" + - "BmbqO8A95PeqQEWHvM5nchlV1+ZGNVqHHSJenlMnVKytGv+4KJp7U741H/9cMbd2\n" + - "X2PXsewWWFhGXoS8R9VXQ5xb3hF6324FQXvcA1mXRv6DAJedXQIDAQABo4IBCzCC\n" + - "AQcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRHuM3/5W/u+LLsL04O+SWw\n" + - "jjxrwzAdBgNVHQ4EFgQUIjAu0vv2S8rAuDvSBMTpcuaXmwwwDgYDVR0PAQH/BAQD\n" + - "AgEGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjARBgNVHSAECjAIMAYG\n" + - "BFUdIAAwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2NybC5idXlwYXNzLm5vL2Ny\n" + - "bC9CUENsYXNzM1Jvb3RDQS5jcmwwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzAB\n" + - "hhdodHRwOi8vb2NzcC5idXlwYXNzLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAo42Y\n" + - "fp96nUiZbZsqvYBID3Sqtx3jJfU8gNHFeXgkS0pxYHHYUwsVSVRjw+BGVEGUswpF\n" + - "MaYMCZD37ZL0JpvvXWrCDaMb/GqDJAQHLLTyVKPGGGIWCZH/FrhnNvcpt2XXA8lU\n" + - "Ujzp5nZPuqvenzQ/aXHI4sH5sN/QjyKVMSa/6RbWBeQmvIdgyM+0jIR5/r6UGiKM\n" + - "ar55trZgnlIbvQJ/w8QTmI/NwvA5CtRaOslQBxeKoAR0BuA/lRWnocXa/BM5uO6P\n" + - "ULL7ct/uI1bS+YThHXHmFybI6kDf+RhRzWY9165ZP96PBph6smQkxPDAz2b8v+mh\n" + - "LThH+5hkqnoetYfK2MdBYinceGPP3gZ+uBSDDI2o6vdVvdg7G96GP1OEtgTEqZa3\n" + - "glVafckpn/8F5CisypdQuZ5zyy/6SXZCKkPcikR87ysSKnjtteXbxMWVtwkeBALT\n" + - "K7DbJA+5aOCYRNj6CJGULQKiGlC01/ipORKewf5J3yus81lLHzBmgQMA5l9RL8rV\n" + - "6dI246mPpQ+8WDLsDrK3ydSDv5izgdVHzhL0tT2u4vwSq2WUqCgi4xLIA1N/fA2H\n" + - "xEW7zh0X/3YVz++g/6bd7iqRD9nRRZxACekRbza7AqU5xN1UjvVtCJQ9VC74K9KP\n" + - "pBoLWE2Bz5ksL9VUc4kS+WGORvZrSE1EpBq6cHc=\n" + - "-----END CERTIFICATE-----"; - - // Owner: SERIALNUMBER=983163327, CN=valid.businessplus.ca23.ssl.buypass.no, O=BUYPASS AS, - // L=OSLO, OID.2.5.4.17=0484, C=NO - // Issuer: CN=Buypass Class 3 CA 2, O=Buypass AS-983163327, C=NO - // Serial number: 267b7a9f0c3da9b94b39 - // Valid from: Mon Sep 23 04:17:42 PDT 2019 until: Mon Oct 11 14:59:00 PDT 2021 - private static final String VALID_CLASS_3 = "-----BEGIN CERTIFICATE-----\n" + - "MIIGUTCCBTmgAwIBAgIKJnt6nww9qblLOTANBgkqhkiG9w0BAQsFADBLMQswCQYD\n" + - "VQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMM\n" + - "FEJ1eXBhc3MgQ2xhc3MgMyBDQSAyMB4XDTE5MDkyMzExMTc0MloXDTIxMTAxMTIx\n" + - "NTkwMFowgYUxCzAJBgNVBAYTAk5PMQ0wCwYDVQQRDAQwNDg0MQ0wCwYDVQQHDARP\n" + - "U0xPMRMwEQYDVQQKDApCVVlQQVNTIEFTMS8wLQYDVQQDDCZ2YWxpZC5idXNpbmVz\n" + - "c3BsdXMuY2EyMy5zc2wuYnV5cGFzcy5ubzESMBAGA1UEBRMJOTgzMTYzMzI3MIIB\n" + - "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArqj6dPVIQUULBV/S+u2/Rfko\n" + - "3BljX/KMEAclJHPu6AbJ2Dw5oLqCynOfTwLmGl3IRBQuDUAuoLdaptIhaXR2VTsF\n" + - "8SWdHNXkykC2eD0XkAUdTuKgRm/3U4f0T3XQsjwKOEQGECwGEWJekBL73retSRWe\n" + - "Ccc19NpSKZ5rmRnQSlKLfqUyihmw2xXmIWwEmBq0OOyG8ic3C11Zxh6yUOtlZJqB\n" + - "lWqbAAOK5SXTNV0qozwgkSvtAtJvUo2++rng35Oj8MvjKQjLi92NnSpjbj3rUivW\n" + - "++44X94IgoF9dITkSMnubXhaTLnciM08R8jmCFj877NRrVJRmcJhPfP1yHnR3wID\n" + - "AQABo4IC+jCCAvYwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBQiMC7S+/ZLysC4O9IE\n" + - "xOly5pebDDAdBgNVHQ4EFgQUKJCKAxRR7K6pedVONDSn58EOzQcwDgYDVR0PAQH/\n" + - "BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAfBgNVHSAEGDAW\n" + - "MAoGCGCEQgEaAQMEMAgGBmeBDAECAjA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8v\n" + - "Y3JsLmJ1eXBhc3Mubm8vY3JsL0JQQ2xhc3MzQ0EyLmNybDAxBgNVHREEKjAogiZ2\n" + - "YWxpZC5idXNpbmVzc3BsdXMuY2EyMy5zc2wuYnV5cGFzcy5ubzBqBggrBgEFBQcB\n" + - "AQReMFwwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmJ1eXBhc3MuY29tMDUGCCsG\n" + - "AQUFBzAChilodHRwOi8vY3J0LmJ1eXBhc3Mubm8vY3J0L0JQQ2xhc3MzQ0EyLmNl\n" + - "cjCCAXwGCisGAQQB1nkCBAIEggFsBIIBaAFmAHYAu9nfvB+KcbWTlCOXqpJ7RzhX\n" + - "lQqrUugakJZkNo4e0YUAAAFtXdd3CgAABAMARzBFAiEA/pTOtw6i2DJS0R56KwVF\n" + - "Huy+LonG7bICWAe1vnCNud4CIE7/KRDu9Jys24rtmLz9yCNYJfZDvooK5PT9+rWR\n" + - "OC4+AHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFtXdd54gAA\n" + - "BAMARjBEAiB09qp4sGA+Kxg823hea3ZyTV7mU1ZQ9j9fqqX8KZ1mpwIgUICM2H0Y\n" + - "8z+V9m+6SutZ5WTD+Arg3K8O6/dvyKu0QmEAdQBvU3asMfAxGdiZAKRRFf93FRwR\n" + - "2QLBACkGjbIImjfZEwAAAW1d13cSAAAEAwBGMEQCIFLqxvNOKVFlTjHPXwk93VeW\n" + - "zCqFtcxJkunD/iiv0Kn9AiBoyvUrjYn4MPTht9zb0OyaSMWb00/HXP/4AVmUzHrz\n" + - "YzANBgkqhkiG9w0BAQsFAAOCAQEAsmQAOn1f1CbvnOpggS2efmy1pQXvvw+YeCYP\n" + - "bElO578h7scn8al4N7huQZ/z14BELe0chGWNA/ReW5nAu3SUOiv+E8/kv9i9Y8ul\n" + - "MJPL62nXW6Z/mkyystuBNtON420iWL/gS/vduxSZE/iBB4znctDpXS917/XWf31Y\n" + - "ZonemF3MSfi/s9V0Ic82ZY/+HZ4NLTDyKRd4kFF58OoH9RZNb6g8MbTp+gPadiUG\n" + - "UcfPGV3yGiugQa7WHTl7QJ9ishyafiZ4hpeKem6TMDEztgGyLIZ4MSxQvoeI2jJP\n" + - "KjHd5fW/HClbEcrN+w0a0MUNMaAOaZfMS7jS6sDpaVL8D0EX5A==\n" + - "-----END CERTIFICATE-----"; - - // Owner: SERIALNUMBER=983163327, CN=revoked.businessplus.ca23.ssl.buypass.no, O=BUYPASS AS, - // L=OSLO, OID.2.5.4.17=0484, C=NO - // Issuer: CN=Buypass Class 3 CA 2, O=Buypass AS-983163327, C=NO - // Serial number: 267cee3fab06c615fb27 - // Valid from: Mon Sep 23 04:56:56 PDT 2019 until: Thu Sep 23 14:59:00 PDT 2021 - private static final String REVOKED_CLASS_3 = "-----BEGIN CERTIFICATE-----\n" + - "MIIGWDCCBUCgAwIBAgIKJnzuP6sGxhX7JzANBgkqhkiG9w0BAQsFADBLMQswCQYD\n" + - "VQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMM\n" + - "FEJ1eXBhc3MgQ2xhc3MgMyBDQSAyMB4XDTE5MDkyMzExNTY1NloXDTIxMDkyMzIx\n" + - "NTkwMFowgYcxCzAJBgNVBAYTAk5PMQ0wCwYDVQQRDAQwNDg0MQ0wCwYDVQQHDARP\n" + - "U0xPMRMwEQYDVQQKDApCVVlQQVNTIEFTMTEwLwYDVQQDDChyZXZva2VkLmJ1c2lu\n" + - "ZXNzcGx1cy5jYTIzLnNzbC5idXlwYXNzLm5vMRIwEAYDVQQFEwk5ODMxNjMzMjcw\n" + - "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtpNExWd+hjl/ouL/B/pdc\n" + - "InUzEywQO3rzXs3psBdQ1lDhG/9Fcq78uqyri4edtJNDGb1XadktKeRC+NtUqMkE\n" + - "IFOXvaVjLxa61c8K5mh3CVDrAiPyxVcnm8vkuQPMsy1BTOl9TZq9heIukG/lcfzW\n" + - "6tU6mOD9yx1NzXSVN5cvDCbbDnEZiJSuazXI4O02as66SWI27WKsk21+SKCGAtGC\n" + - "kI0PW4FrXm43/jxX1CoImIfTLkDInMq7HHsQRsGQ3OjbJLfRz/2obyjHUU5ki6vd\n" + - "z16mA5ITLFIG36HxbPn337175R9RwOpWkN84xVlL3VQdznCVoiOjzBiOMpdm0Jwp\n" + - "AgMBAAGjggL/MIIC+zAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFCIwLtL79kvKwLg7\n" + - "0gTE6XLml5sMMB0GA1UdDgQWBBSGUQTUB4BilG/EMaHHDAYNPewf8zAOBgNVHQ8B\n" + - "Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB8GA1UdIAQY\n" + - "MBYwCgYIYIRCARoBAwQwCAYGZ4EMAQICMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6\n" + - "Ly9jcmwuYnV5cGFzcy5uby9jcmwvQlBDbGFzczNDQTIuY3JsMDMGA1UdEQQsMCqC\n" + - "KHJldm9rZWQuYnVzaW5lc3NwbHVzLmNhMjMuc3NsLmJ1eXBhc3Mubm8wagYIKwYB\n" + - "BQUHAQEEXjBcMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5idXlwYXNzLmNvbTA1\n" + - "BggrBgEFBQcwAoYpaHR0cDovL2NydC5idXlwYXNzLm5vL2NydC9CUENsYXNzM0NB\n" + - "Mi5jZXIwggF/BgorBgEEAdZ5AgQCBIIBbwSCAWsBaQB2ALvZ37wfinG1k5Qjl6qS\n" + - "e0c4V5UKq1LoGpCWZDaOHtGFAAABbV37Y7oAAAQDAEcwRQIgYbaNSR3R5x9p9sYJ\n" + - "UzRDdd/lbELb05u9GqlLtl4M61YCIQCTBecXTbMs4zuG/wu722HZy/XgD6fiQySp\n" + - "FhHDO3CYagB2AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABbV37\n" + - "Y7wAAAQDAEcwRQIgD8j40M03oLMCg5WmFBN7VL6169F7rKatE12btLQRYtYCIQC0\n" + - "rDhQiZP7j14Y4JqEFQx6UHl3dvxLxZTDW34Z54IUWQB3AG9Tdqwx8DEZ2JkApFEV\n" + - "/3cVHBHZAsEAKQaNsgiaN9kTAAABbV37YOUAAAQDAEgwRgIhANTGHD1g2pbsTtoN\n" + - "CJ2m6nfxm9jB3huftKGDjeo7EyxHAiEA3EYNUc6hr+4Q9lMAphUgpW6oyaNCsIzl\n" + - "izbNhq8dBRYwDQYJKoZIhvcNAQELBQADggEBADUuO4MmYjPkmkik5tjUPiiDDXEQ\n" + - "A41jr72qmdleYdkhnaKAJa8Enn6j/ySRV0enA7yqJeNp1qgPQFvlOh3TqFB3Ae5b\n" + - "XAfL2B7vKbegpjKm8dVH5RurqVm9xZcXb1nbwfu2k3lqqsp/uwqvLBItJDvA8pfi\n" + - "2R46sEtj2gFpAlKFDwepuaklqhrvEoIjIaAL0RrGfKY0oRQw1YMbPNIebsVaWr04\n" + - "rt6tlxrq7PyW1w9Mt3445WA1NzSWc7pAjFLfY6u87QaPHI4ES31H9xxRDsxmr6Y3\n" + - "BJmiWd5uUxev0nVw0saqvlo4yAEBq4rI/DieKcQI4qEI8myzoS0R0azMfLM=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID_CLASS_3, INT_CLASS_3}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED_CLASS_3, INT_CLASS_3}, - ValidatePathWithParams.Status.REVOKED, - "Mon Sep 23 04:57:31 PDT 2019", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,695 @@ +/* + * 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=actalisauthenticationrootca + * @bug 8189131 + * @summary Interoperability tests with Actalis CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp + * CAInterop actalisauthenticationrootca OCSP + * @run main/othervm/timeout=180 -Djava.security.debug=certpath,ocsp + * CAInterop actalisauthenticationrootca CRL + */ + +/* + * @test id=amazonrootca1 + * @bug 8233223 + * @summary Interoperability tests with Amazon's CA1 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca1 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca1 CRL + */ + +/* + * @test id=amazonrootca2 + * @bug 8233223 + * @summary Interoperability tests with Amazon's CA2 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca2 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca2 CRL + */ + +/* + * @test id=amazonrootca3 + * @bug 8233223 + * @summary Interoperability tests with Amazon's CA3 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca3 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca3 CRL + */ + +/* + * @test id=amazonrootca4 + * @bug 8233223 + * @summary Interoperability tests with Amazon's CA4 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca4 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca4 CRL + */ + +/* + * @test id=buypassclass2ca + * @bug 8189131 + * @summary Interoperability tests with Buypass Class 2 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca CRL + */ + +/* + * @test id=buypassclass3ca + * @bug 8189131 + * @summary Interoperability tests with Buypass Class 3 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca CRL + */ + +/* + * @test id=comodorsaca + * @bug 8189131 + * @summary Interoperability tests with Comodo RSA CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodorsaca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop comodorsaca CRL + */ + +/* + * @test id=comodoeccca + * @bug 8189131 + * @summary Interoperability tests with Comodo ECC CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodoeccca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop comodoeccca CRL + */ + +/* + * @test id=usertrustrsaca + * @bug 8189131 + * @summary Interoperability tests with Comodo userTrust RSA CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrustrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop usertrustrsaca CRL + */ + +/* + * @test id=usertrusteccca + * @bug 8189131 + * @summary Interoperability tests with Comodo userTrust ECC CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrusteccca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop usertrusteccca CRL + */ + +/* + * @test id=letsencryptisrgx1 + * @bug 8189131 + * @summary Interoperability tests with Let's Encrypt ISRG Root X1 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx1 DEFAULT + */ + +/* + * @test id=letsencryptisrgx2 + * @bug 8317374 + * @summary Interoperability tests with Let's Encrypt ISRG Root X2 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx2 DEFAULT + */ + +/* + * @test id=globalsignrootcar6 + * @bug 8216577 + * @summary Interoperability tests with GlobalSign R6 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsignrootcar6 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop globalsignrootcar6 CRL + */ + +/* + * @test id=entrustrootcaec1 + * @bug 8195774 + * @summary Interoperability tests with Entrust CAs + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcaec1 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcaec1 CRL + */ + +/* + * @test id=entrustrootcag4 + * @bug 8243321 + * @summary Interoperability tests with Entrust CAs + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcag4 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcag4 CRL + */ + +/* + * @test id=godaddyrootg2ca + * @bug 8196141 + * @summary Interoperability tests with GoDaddy CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop godaddyrootg2ca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop godaddyrootg2ca CRL + */ + +/* + * @test id=starfieldrootg2ca + * @bug 8196141 + * @summary Interoperability tests with Starfield CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop starfieldrootg2ca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop starfieldrootg2ca CRL + */ + +/* + * @test id=globalsigneccrootcar4 + * @bug 8307134 + * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop globalsigneccrootcar4 CRL + */ + +/* + * @test id=gtsrootcar1 + * @bug 8307134 + * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootcar1 CRL + */ + +/* + * @test id=gtsrootcar2 + * @bug 8307134 + * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootcar2 CRL + */ + +/* + * @test id=gtsrootecccar3 + * @bug 8307134 + * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootecccar3 CRL + */ + +/* + * @test id=gtsrootecccar4 + * @bug 8307134 + * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootecccar4 CRL + */ + +/* + * @test id=microsoftecc2017 + * @bug 8304760 + * @summary Interoperability tests with Microsoft TLS root CAs + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftecc2017 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftecc2017 CRL + */ + +/* + * @test id=microsoftrsa2017 + * @bug 8304760 + * @summary Interoperability tests with Microsoft TLS root CAs + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftrsa2017 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftrsa2017 CRL + */ + +/* + * @test id=quovadisrootca1g3 + * @bug 8189131 + * @summary Interoperability tests with QuoVadis Root CA1 G3 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca1g3 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca1g3 CRL + */ + +/* + * @test id=quovadisrootca2g3 + * @bug 8189131 + * @summary Interoperability tests with QuoVadis Root CA2 G3 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca2g3 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca2g3 CRL + */ + +/* + * @test id=quovadisrootca3g3 + * @bug 8189131 + * @summary Interoperability tests with QuoVadis Root CA3 G3 CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca3g3 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca3g3 CRL + */ + +/* + * @test id=digicerttlseccrootg5 + * @bug 8318759 + * @summary Interoperability tests with DigiCert TLS ECC P384 Root G5 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlseccrootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlseccrootg5 CRL + */ + +/* + * @test id=digicerttlsrsarootg5 + * @bug 8318759 + * @summary Interoperability tests with DigiCert TLS RSA4096 Root G5 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlsrsarootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlsrsarootg5 CRL + */ + +/* + * @test id=sslrootrsaca + * @bug 8243320 + * @summary Interoperability tests with SSL.com's RSA CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootrsaca CRL + */ + +/* + * @test id=sslrootevrsaca + * @bug 8243320 + * @summary Interoperability tests with SSL.com's EV RSA CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootevrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootevrsaca CRL + */ + +/* + * @test id=sslrooteccca + * @bug 8243320 + * @summary Interoperability tests with SSL.com's ECC CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrooteccca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop sslrooteccca CRL + */ + +/* + * @test id=teliasonerarootcav1 + * @bug 8210432 + * @summary Interoperability tests with TeliaSonera Root CA v1 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliasonerarootcav1 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop teliasonerarootcav1 CRL + */ + +/* + * @test id=twcaglobalrootca + * @bug 8305975 + * @summary Interoperability tests with TWCA Global Root CA from TAIWAN-CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop twcaglobalrootca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop twcaglobalrootca CRL + */ + +/* + * @test id=certignarootca + * @bug 8314960 + * @summary Interoperability tests with Certigna Root CAs from Dhimyotis + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certignarootca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop certignarootca CRL + */ + +/* + * @test id=affirmtrustcommercialca + * @bug 8040012 + * @summary Interoperability tests with AffirmTrust Commercial CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustcommercialca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustcommercialca CRL + */ + +/* + * @test id=affirmtrustnetworkingca + * @bug 8040012 + * @summary Interoperability tests with AffirmTrust Networking CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustnetworkingca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustnetworkingca CRL + */ + +/* + * @test id=affirmtrustpremiumca + * @bug 8040012 + * @summary Interoperability tests with AffirmTrust Premium CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumca CRL + */ + +/* + * @test id=affirmtrustpremiumeccca + * @bug 8040012 + * @summary Interoperability tests with AffirmTrust Premium ECC CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumeccca OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumeccca CRL + */ + +/* + * @test id=teliarootcav2 + * @bug 8317373 + * @summary Interoperability tests with Telia Root CA V2 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliarootcav2 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop teliarootcav2 CRL + */ + +/* + * @test id=emsignrootcag1 + * @bug 8319187 + * @summary Interoperability tests with eMudhra Root CA G1 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsignrootcag1 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop emsignrootcag1 CRL + */ + +/* + * @test id=emsigneccrootcag3 + * @bug 8319187 + * @summary Interoperability tests with eMudhra ECC Root CA G3 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsigneccrootcag3 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop emsigneccrootcag3 CRL + */ + +/** + * Collection of certificate validation tests for interoperability with external CAs + */ +public class CAInterop { + + /** + * Returns the test configuration for CA + * + * @param alias from the cacerts file without [jdk] + * @return CATestURLs + */ + private CATestURLs getTestURLs(String alias) { + return switch (alias) { + case "actalisauthenticationrootca" -> + new CATestURLs("https://ssltest-active.actalis.it", + "https://ssltest-revoked.actalis.it"); + + case "amazonrootca1" -> + new CATestURLs("https://valid.rootca1.demo.amazontrust.com", + "https://revoked.rootca1.demo.amazontrust.com"); + case "amazonrootca2" -> + new CATestURLs("https://valid.rootca2.demo.amazontrust.com", + "https://revoked.rootca2.demo.amazontrust.com"); + case "amazonrootca3" -> + new CATestURLs("https://valid.rootca3.demo.amazontrust.com", + "https://revoked.rootca3.demo.amazontrust.com"); + case "amazonrootca4" -> + new CATestURLs("https://valid.rootca4.demo.amazontrust.com", + "https://revoked.rootca4.demo.amazontrust.com"); + + case "buypassclass2ca" -> + new CATestURLs("https://valid.business.ca22.ssl.buypass.no", + "https://revoked.business.ca22.ssl.buypass.no"); + case "buypassclass3ca" -> + new CATestURLs("https://valid.qcevident.ca23.ssl.buypass.no", + "https://revoked.qcevident.ca23.ssl.buypass.no"); + + case "comodorsaca" -> + new CATestURLs("https://comodorsacertificationauthority-ev.comodoca.com", + "https://comodorsacertificationauthority-ev.comodoca.com:444"); + case "comodoeccca" -> + new CATestURLs("https://comodoecccertificationauthority-ev.comodoca.com", + "https://comodoecccertificationauthority-ev.comodoca.com:444"); + case "usertrustrsaca" -> + new CATestURLs("https://usertrustrsacertificationauthority-ev.comodoca.com", + "https://usertrustrsacertificationauthority-ev.comodoca.com:444"); + case "usertrusteccca" -> + new CATestURLs("https://usertrustecccertificationauthority-ev.comodoca.com", + "https://usertrustecccertificationauthority-ev.comodoca.com:444"); + + case "letsencryptisrgx1" -> + new CATestURLs("https://valid-isrgrootx1.letsencrypt.org", + "https://revoked-isrgrootx1.letsencrypt.org"); + case "letsencryptisrgx2" -> + new CATestURLs("https://valid-isrgrootx2.letsencrypt.org", + "https://revoked-isrgrootx2.letsencrypt.org"); + + case "globalsignrootcar6" -> + new CATestURLs("https://valid.r6.roots.globalsign.com", + "https://revoked.r6.roots.globalsign.com"); + + case "entrustrootcaec1" -> + new CATestURLs("https://validec.entrust.net", + "https://revokedec.entrust.net"); + case "entrustrootcag4" -> + new CATestURLs("https://validg4.entrust.net", + "https://revokedg4.entrust.net"); + + case "godaddyrootg2ca" -> + new CATestURLs("https://valid.gdig2.catest.godaddy.com", + "https://revoked.gdig2.catest.godaddy.com"); + case "starfieldrootg2ca" -> + new CATestURLs("https://valid.sfig2.catest.starfieldtech.com", + "https://revoked.sfig2.catest.starfieldtech.com"); + + case "globalsigneccrootcar4" -> + new CATestURLs("https://good.gsr4.demo.pki.goog", + "https://revoked.gsr4.demo.pki.goog"); + case "gtsrootcar1" -> + new CATestURLs("https://good.gtsr1.demo.pki.goog", + "https://revoked.gtsr1.demo.pki.goog"); + case "gtsrootcar2" -> + new CATestURLs("https://good.gtsr2.demo.pki.goog", + "https://revoked.gtsr2.demo.pki.goog"); + case "gtsrootecccar3" -> + new CATestURLs("https://good.gtsr3.demo.pki.goog", + "https://revoked.gtsr3.demo.pki.goog"); + case "gtsrootecccar4" -> + new CATestURLs("https://good.gtsr4.demo.pki.goog", + "https://revoked.gtsr4.demo.pki.goog"); + + case "microsoftecc2017" -> + new CATestURLs("https://acteccroot2017.pki.microsoft.com", + "https://rvkeccroot2017.pki.microsoft.com"); + case "microsoftrsa2017" -> + new CATestURLs("https://actrsaroot2017.pki.microsoft.com", + "https://rvkrsaroot2017.pki.microsoft.com"); + + // Test URLs are listed at https://www.digicert.com/kb/digicert-root-certificates.htm + case "quovadisrootca1g3" -> + new CATestURLs("https://quovadis-root-ca-1-g3.chain-demos.digicert.com", + "https://quovadis-root-ca-1-g3-revoked.chain-demos.digicert.com"); + case "quovadisrootca2g3" -> + new CATestURLs("https://quovadis-root-ca-2-g3.chain-demos.digicert.com", + "https://quovadis-root-ca-2-g3-revoked.chain-demos.digicert.com"); + case "quovadisrootca3g3" -> + new CATestURLs("https://quovadis-root-ca-3-g3.chain-demos.digicert.com", + "https://quovadis-root-ca-3-g3-revoked.chain-demos.digicert.com"); + case "digicerttlseccrootg5" -> + new CATestURLs("https://digicert-tls-ecc-p384-root-g5.chain-demos.digicert.com", + "https://digicert-tls-ecc-p384-root-g5-revoked.chain-demos.digicert.com"); + case "digicerttlsrsarootg5" -> + new CATestURLs("https://digicert-tls-rsa4096-root-g5.chain-demos.digicert.com", + "https://digicert-tls-rsa4096-root-g5-revoked.chain-demos.digicert.com"); + + case "sslrootrsaca" -> + new CATestURLs("https://test-dv-rsa.ssl.com", + "https://revoked-rsa-dv.ssl.com"); + case "sslrootevrsaca" -> + new CATestURLs("https://test-ev-rsa.ssl.com", + "https://revoked-rsa-ev.ssl.com"); + case "sslrooteccca" -> + new CATestURLs("https://test-dv-ecc.ssl.com", + "https://revoked-ecc-dv.ssl.com"); + + case "teliasonerarootcav1" -> + new CATestURLs("https://juolukka.cover.sonera.net:10443", + "https://juolukka.cover.sonera.net:10444"); + + case "twcaglobalrootca" -> + new CATestURLs("https://evssldemo6.twca.com.tw", + "https://evssldemo7.twca.com.tw"); + + case "certignarootca" -> + new CATestURLs("https://valid.servicesca.dhimyotis.com", + "https://revoked.servicesca.dhimyotis.com"); + + // These are listed at https://www.affirmtrust.com/resources/ + case "affirmtrustcommercialca" -> + new CATestURLs("https://validcommercial.affirmtrust.com", + "https://revokedcommercial.affirmtrust.com"); + case "affirmtrustnetworkingca" -> + new CATestURLs("https://validnetworking.affirmtrust.com", + "https://revokednetworking.affirmtrust.com"); + case "affirmtrustpremiumca" -> + new CATestURLs("https://validpremium.affirmtrust.com", + "https://revokedpremium.affirmtrust.com"); + case "affirmtrustpremiumeccca" -> + new CATestURLs("https://validpremiumecc.affirmtrust.com", + "https://revokedpremiumecc.affirmtrust.com"); + + case "teliarootcav2" -> + new CATestURLs("https://juolukka.cover.telia.fi:10600", + "https://juolukka.cover.telia.fi:10601"); + + case "emsignrootcag1" -> + new CATestURLs("https://testovg1.emsign.com/RootOVG1.html", + "https://testovg1r.emsign.com/RootOVG1MR.html"); + case "emsigneccrootcag3" -> + new CATestURLs("https://testovg3.emsign.com/RootOVG3.html", + "https://testovg3r.emsign.com/RootOVG3MR.html"); + + default -> throw new RuntimeException("No test setup found for: " + alias); + }; + } + + public static void main(String[] args) throws Exception { + if (args.length < 2) { + throw new RuntimeException("Run as: CAInterop "); + } + + String caAlias = args[0]; + + CAInterop caInterop = new CAInterop(args[1]); + CATestURLs caTestURLs = caInterop.getTestURLs(caAlias); + + caInterop.validate(caAlias + " [jdk]", + caTestURLs.getVALID_URL(), + caTestURLs.getREVOKED_URL()); + } + + static class CATestURLs { + final String VALID_URL; + final String REVOKED_URL; + + public CATestURLs(String validURL, + String revokedURL) { + VALID_URL = validURL; + REVOKED_URL = revokedURL; + } + + public String getVALID_URL() { + return VALID_URL; + } + + public String getREVOKED_URL() { + return REVOKED_URL; + } + } + + /** + * Constructor for interoperability test with third party CA. + * + * @param revocationMode revocation checking mode to use + */ + public CAInterop(String revocationMode) { + if ("CRL".equalsIgnoreCase(revocationMode)) { + ValidatePathWithURL.enableCRLOnly(); + } else if ("OCSP".equalsIgnoreCase(revocationMode)) { + ValidatePathWithURL.enableOCSPOnly(); + } else { + // OCSP and CRL check by default + ValidatePathWithURL.enableOCSPAndCRL(); + } + + ValidatePathWithURL.logRevocationSettings(); + } + + /** + * Validates provided URLs using HttpsURLConnection making sure they + * anchor to the root CA found in cacerts using provided alias. + * + * @param caAlias CA alis from cacerts file + * @param validCertURL valid test URL + * @param revokedCertURL revoked test URL + * @throws Exception thrown when certificate can't be validated as valid or revoked + */ + public void validate(String caAlias, + String validCertURL, + String revokedCertURL) throws Exception { + + ValidatePathWithURL validatePathWithURL = new ValidatePathWithURL(caAlias); + + if (validCertURL != null) { + validatePathWithURL.validateDomain(validCertURL, false); + } + + if (revokedCertURL != null) { + validatePathWithURL.validateDomain(revokedCertURL, true); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,220 @@ +/* + * 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 8245654 8256895 + * @summary Interoperability tests with Certigna Root CAs from Dhimyotis + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=certpath CertignaCA OCSP + * @run main/othervm -Djava.security.debug=certpath CertignaCA CRL + */ +public class CertignaCA { + // Owner: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, + // OU=0002 48146308100036, O=DHIMYOTIS, C=FR + // Issuer: CN=Certigna, O=Dhimyotis, C=FR + // Serial number: 6f82fa28acd6f784bb5b120ba87367ad + // Valid from: Wed Nov 25 03:33:52 PST 2015 until: Sat Nov 22 03:33:52 PST 2025 + private static final String INT_CERTIGNA = "-----BEGIN CERTIFICATE-----\n" + + "MIIGFjCCBP6gAwIBAgIQb4L6KKzW94S7WxILqHNnrTANBgkqhkiG9w0BAQsFADA0\n" + + "MQswCQYDVQQGEwJGUjESMBAGA1UECgwJRGhpbXlvdGlzMREwDwYDVQQDDAhDZXJ0\n" + + "aWduYTAeFw0xNTExMjUxMTMzNTJaFw0yNTExMjIxMTMzNTJaMH0xCzAJBgNVBAYT\n" + + "AkZSMRIwEAYDVQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgx\n" + + "MDAwMzYxHTAbBgNVBGEMFE5UUkZSLTQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQQDDBRD\n" + + "ZXJ0aWduYSBTZXJ2aWNlcyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n" + + "ggIBALPM+7LpWBz9wFcPaTc3xnB+5g0XrnptB0EPPfrR04vO52Ykm4ky1d4ZLd10\n" + + "tbM1fa1RqNSOVWWg93O4pL7zCFKlz6JV74ZZVhHpEAwzBwv2oPnxvVbxtSN67xsS\n" + + "Y66ahUYxjzs8+3FhmsiRxqwnTYvK2u70uglUvRisOKyTL/M6JnrC4y8tlmoz7OSa\n" + + "5BmBMVplJFQtvmON6N9aHLvYMz+EyJPCbXL6pELxeHjFT5QmIaRamsr2DOTaCjtB\n" + + "ZKI1Wnh3X7lnbjM8MESJiV2t7E9tIQNG0Z/HI3tO4aaUMum3KysY5sC8v3vi7rry\n" + + "GidgzHQhrtP0ZXWW5UH/k7umLS/P/XXWnCFpc2Lxa1uDGfc2im7xibRoPP+JNZsz\n" + + "N76euFlls6jyEXAiwnVr14tVVTewLK0OWs5SJHpEKp8PGMZRDj59EmMvokWwzL6Q\n" + + "zNZ6vVAp00oOm05sbspNY9+MFqGKKUsKvhFGEa4XmRNxDe6KswLcjPZB+NKHZ0QW\n" + + "Fd4ip5C5XmEK/8qIPjwVr9dah9+oiHGGO8Wx7gJAMF5DTmkvW7GhqCKj1LmHnabj\n" + + "zc8av6kxWVQZi/C7HCm9i/W4wio+JA2EAFLqNL3GPNbK9kau4yPhQt/c7zxzo0OH\n" + + "nlsV4THCG7oOCd3cfCiyfQcb3FBt6OSpaKRZxjCLBwP00r0fAgMBAAGjggHZMIIB\n" + + "1TASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU\n" + + "rOyGj0s3HLh/FxsZ0K7oTuM0XBIwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF\n" + + "9lo53BGhOKQ2MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAP\n" + + "BgNVBAMMCENlcnRpZ25hggkA/tzjAQ/JSP8wSQYDVR0gBEIwQDA+BgoqgXoBgTEB\n" + + "AAECMDAwLgYIKwYBBQUHAgEWImh0dHBzOi8vd3d3LmNlcnRpZ25hLmZyL2F1dG9y\n" + + "aXRlcy8wfAYIKwYBBQUHAQEEcDBuMDQGCCsGAQUFBzAChihodHRwOi8vYXV0b3Jp\n" + + "dGUuY2VydGlnbmEuZnIvY2VydGlnbmEuZGVyMDYGCCsGAQUFBzAChipodHRwOi8v\n" + + "YXV0b3JpdGUuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5kZXIwYQYDVR0fBFowWDAp\n" + + "oCegJYYjaHR0cDovL2NybC5jZXJ0aWduYS5mci9jZXJ0aWduYS5jcmwwK6ApoCeG\n" + + "JWh0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5jcmwwDQYJKoZIhvcN\n" + + "AQELBQADggEBAGLft7gIuGPZVfg0cTM+HT2xAZFPDb/2+siH06x+dH044zMKbBIN\n" + + "bRzhKipwB1A3MW8FQjveE9tyrfyuqZE/X+o2SlGcdNV44ybYkxo4f6kcLEavV/IW\n" + + "+oFEnojZlhpksYcxrvQoEyqkAwshe8IS2KtZHKVACrt+XSs0lwvy7ALGmHaF7A4b\n" + + "y6cZWItA7Lhj8XWp+8tBJDj7HocRbWtxzEODdBuyMgJzFrNjc+97J0vH/K0+3yjm\n" + + "kczpKshMA0tM+MF9XDMN/MuwrPmUWGO/fHiqHgUp8yqeWtl1n44ZxkkK1t9GRwhn\n" + + "DWLv73/xhTmdhWYQ/reo0GbgBoLiltKmIJQ=\n" + + "-----END CERTIFICATE-----"; + + // Owner: SERIALNUMBER=S266241169, CN=valid.servicesca.dhimyotis.com, O=DHIMYOTIS, + // L=VILLENEUVE D'ASCQ, C=FR + // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, OU=0002 + // 48146308100036, O=DHIMYOTIS, C=FR + // Serial number: c641ef7b0340c21515d8c462e729dc0e + // Valid from: Thu Mar 09 15:00:00 PST 2023 until: Mon Mar 11 15:59:59 PDT 2024 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIIdzCCBl+gAwIBAgIRAMZB73sDQMIVFdjEYucp3A4wDQYJKoZIhvcNAQELBQAw\n" + + "fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw\n" + + "MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx\n" + + "HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIzMDMwOTIzMDAwMFoX\n" + + "DTI0MDMxMTIyNTk1OVowezELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + + "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxJzAlBgNVBAMMHnZhbGlkLnNl\n" + + "cnZpY2VzY2EuZGhpbXlvdGlzLmNvbTETMBEGA1UEBRMKUzI2NjI0MTE2OTCCASIw\n" + + "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJDrFpZWEeBJoMUuG37wEmJ7XVeX\n" + + "Jde1bgURpFbLwifRj2TVmMdtfg9hXHL7B7Mh/+I8/e7kJz8mlU9qUYKyH24oAitE\n" + + "myXYHAKTydqTseiM3mp92n4PM+DrgsdbT7bpmiirNM0/sqWFNyGUz7kP6Z5E3uuU\n" + + "HSlzX1LBBj8S0ORNZWvomQho11gjuZJRS72X4XTnSc0DESwnLp2irUfx7pflBNt0\n" + + "sLE8BhpNSSQd91naJVKtCtn0H7df+o4gGBt2ZceCLBwU0NwN8+KXz06KjP8298V4\n" + + "P3+eR2QxAw4QBIanRaG6Gd4AmpdIaT7TpiYHotjrJ/Pbx5C8/cmgxxlmtI0CAwEA\n" + + "AaOCA/IwggPuMIHkBggrBgEFBQcBAQSB1zCB1DA2BggrBgEFBQcwAoYqaHR0cDov\n" + + "L2F1dG9yaXRlLmNlcnRpZ25hLmZyL3NlcnZpY2VzY2EuZGVyMDgGCCsGAQUFBzAC\n" + + "hixodHRwOi8vYXV0b3JpdGUuZGhpbXlvdGlzLmNvbS9zZXJ2aWNlc2NhLmRlcjAu\n" + + "BggrBgEFBQcwAYYiaHR0cDovL3NlcnZpY2VzY2Eub2NzcC5jZXJ0aWduYS5mcjAw\n" + + "BggrBgEFBQcwAYYkaHR0cDovL3NlcnZpY2VzY2Eub2NzcC5kaGlteW90aXMuY29t\n" + + "MB8GA1UdIwQYMBaAFKzsho9LNxy4fxcbGdCu6E7jNFwSMAkGA1UdEwQCMAAwYQYD\n" + + "VR0gBFowWDAIBgZngQwBAgIwTAYLKoF6AYExAgUBAQEwPTA7BggrBgEFBQcCARYv\n" + + "aHR0cHM6Ly93d3cuY2VydGlnbmEuY29tL2F1dG9yaXRlLWNlcnRpZmljYXRpb24w\n" + + "ZQYDVR0fBF4wXDAtoCugKYYnaHR0cDovL2NybC5kaGlteW90aXMuY29tL3NlcnZp\n" + + "Y2VzY2EuY3JsMCugKaAnhiVodHRwOi8vY3JsLmNlcnRpZ25hLmZyL3NlcnZpY2Vz\n" + + "Y2EuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIFoDBIBgNV\n" + + "HREEQTA/gh12YWxpZC5zZXJ2aWNlc2NhLmNlcnRpZ25hLmNvbYIedmFsaWQuc2Vy\n" + + "dmljZXNjYS5kaGlteW90aXMuY29tMB0GA1UdDgQWBBSzyYZfPBt65RUDq98+e0AK\n" + + "U8pd/jCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHcA7s3QZNXbGs7FXLedtM0T\n" + + "ojKHRny87N7DUUhZRnEftZsAAAGGy1ZNXwAABAMASDBGAiEAyG838/RfBOpojEI/\n" + + "cx++f0tvuDbc/rVa0WNcd2f9HekCIQDVKV2wI3VkD3wNmO93m022H7kvKD1OBEhw\n" + + "Tn6+0ZLA6QB2AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABhstW\n" + + "TcYAAAQDAEcwRQIhAOuj/r5G1wHNgFOMg3jsr3uWmWzIIkTmwmp4hJqvsJzzAiBf\n" + + "nm/jZCUW8DFY+iC+O/+Hzsk/kVDkKIlBDd6rA3MzJgB2AFWB1MIWkDYBSuoLm1c8\n" + + "U/DA5Dh4cCUIFy+jqh0HE9MMAAABhstWTw4AAAQDAEcwRQIgRbCAqI1/nxc6P4de\n" + + "Fqg/zc1+ldMDWjeamWjhctciGsgCIQDHQ4OKj0AA7hQKFIe1SVp+00BxRefFGmq7\n" + + "ZJ+8q+pRqzANBgkqhkiG9w0BAQsFAAOCAgEAVkzCC9LIHU+iOi+GFeCtWxxa5Fsk\n" + + "5gXnDJmtbdoVe2TJvOhrb+VnNI7/Ak+csBv3vxNl3P3DXIbPryB98aelleX7pkfP\n" + + "PcKhFAlbwzbII2D3L0mjFLERtVwdnoEJXXKcHsb9hJResKipZ//daMPD8FthHvEE\n" + + "HmtOrR0lHLjhbi4ODq0e4xyygbxFXXl5CCjtBw0jBtZaMDQaC3eemK9LkOggLz3h\n" + + "qs/+VQ7RyKfcKCuGC5Wb4GJR+IDKH812hFsUWmXe26MPoyTrzLNq6tfQZHSuY5Hj\n" + + "K0ZwldEkUZ2Hd7PrRlhCiGdVCp/2kS2yefhUkvX7Z5K5wX6n+LylfzOTvWf6ZPwQ\n" + + "1jTI0Js8ig4eHF25GlqgOWrqbyF9j67kLs3f7/c5Kx3FlclJ7/vlL8zEcTmGU7rm\n" + + "ZFOhEMDT/UYkitqAOvrgT60oIm9YJ1XTAVTeDbW0FFAb2nFmeBOrw8N3jaCb+jpO\n" + + "ysBA/lDaGTiQhMlJK44vwgS+TjbeWHxvmAE5srKa7MWU8Mmku2vuX95lupJo4LmD\n" + + "zOsihH00hyhtHFUB1TGXuaf77kFsipE6iycyxpcrpJ1UAWiZrba6PAZ85TbYhEdY\n" + + "FDNm7F7CVPU67HV5gE2kDa3Jprd1SjwO095LsRptWhzxUByhee3JI0jljBTaKowy\n" + + "jPv8oekm7zqCLzY=\n" + + "-----END CERTIFICATE-----"; + + // Owner: SERIALNUMBER=S266251168, CN=revoked.servicesca.certigna.com, O=DHIMYOTIS, + // L=VILLENEUVE D'ASCQ, C=FR + // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, OU=0002 + // 48146308100036, O=DHIMYOTIS, C=FR + // Serial number: e863f752a23a735e3ccf958abf18565b + // Valid from: Thu Mar 09 15:00:00 PST 2023 until: Fri Mar 08 14:59:59 PST 2024 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIIezCCBmOgAwIBAgIRAOhj91KiOnNePM+Vir8YVlswDQYJKoZIhvcNAQELBQAw\n" + + "fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw\n" + + "MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx\n" + + "HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIzMDMwOTIzMDAwMFoX\n" + + "DTI0MDMwODIyNTk1OVowfDELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + + "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxKDAmBgNVBAMMH3Jldm9rZWQu\n" + + "c2VydmljZXNjYS5jZXJ0aWduYS5jb20xEzARBgNVBAUTClMyNjYyNTExNjgwggEi\n" + + "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCBqKNjMkHqJ9EQa3CjuZ6EYMz6\n" + + "mWODrEucRcJDihYMigaV1oRyquGlFQ82ootXaK5bU+EYSMmUwbRpdZ9G/oZUn2+K\n" + + "MKAFDI+MoZoFhQC+2w0AzJycCf/hShUVxcRREKRKdfzv+k5YHj3e8ic16tGlTFXT\n" + + "IF1x3y2Uru7mzZARsZJqnRqaqPPghT/QlBpcA04yLi3iSpgO++mRrJxTUoUHlDw/\n" + + "a1nhqnDgH2yKN7tSfwFTetnXat6/UVt0CJ/6dJF6oY8bGWO1YB03Xdq735eLdJE4\n" + + "t38pV/X8rf5Mc9ZQh8IGrjVW83M8mQmqaX5rbsOl0ZCA/q6RWxRFEF2SwK+dAgMB\n" + + "AAGjggP1MIID8TCB5AYIKwYBBQUHAQEEgdcwgdQwNgYIKwYBBQUHMAKGKmh0dHA6\n" + + "Ly9hdXRvcml0ZS5jZXJ0aWduYS5mci9zZXJ2aWNlc2NhLmRlcjA4BggrBgEFBQcw\n" + + "AoYsaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rpcy5jb20vc2VydmljZXNjYS5kZXIw\n" + + "LgYIKwYBBQUHMAGGImh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuY2VydGlnbmEuZnIw\n" + + "MAYIKwYBBQUHMAGGJGh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuZGhpbXlvdGlzLmNv\n" + + "bTAfBgNVHSMEGDAWgBSs7IaPSzccuH8XGxnQruhO4zRcEjAJBgNVHRMEAjAAMGEG\n" + + "A1UdIARaMFgwCAYGZ4EMAQICMEwGCyqBegGBMQIFAQEBMD0wOwYIKwYBBQUHAgEW\n" + + "L2h0dHBzOi8vd3d3LmNlcnRpZ25hLmNvbS9hdXRvcml0ZS1jZXJ0aWZpY2F0aW9u\n" + + "MGUGA1UdHwReMFwwLaAroCmGJ2h0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9zZXJ2\n" + + "aWNlc2NhLmNybDAroCmgJ4YlaHR0cDovL2NybC5jZXJ0aWduYS5mci9zZXJ2aWNl\n" + + "c2NhLmNybDATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBaAwTAYD\n" + + "VR0RBEUwQ4IgcmV2b2tlZC5zZXJ2aWNlc2NhLmRoaW15b3Rpcy5jb22CH3Jldm9r\n" + + "ZWQuc2VydmljZXNjYS5jZXJ0aWduYS5jb20wHQYDVR0OBBYEFEQsKyX8x8zVxVC2\n" + + "HEK7+bOBLoMkMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVc\n" + + "t520zROiModGfLzs3sNRSFlGcR+1mwAAAYbLTxPnAAAEAwBHMEUCIQD16IHX+8+4\n" + + "zWnxIME4rzCgQIA4m5OsEqP6ssgRG5iurwIgdBOGFGlF6+DGPSm5FKuk5ShAA8ZC\n" + + "AE+E27CKLkBTnfgAdgB2/4g/Crb7lVHCYcz1h7o0tKTNuyncaEIKn+ZnTFo6dAAA\n" + + "AYbLTxRMAAAEAwBHMEUCIDmW9elysDm3zAeIXsgJwmL33EoMTyVhA3ah2jkvMjzv\n" + + "AiEA6aIZXtwk2DnFt+GA6gLr4UgswUCuK4wxheDVwbpSw/4AdgA7U3d1Pi25gE6L\n" + + "MFsG/kA7Z9hPw/THvQANLXJv4frUFwAAAYbLTxXAAAAEAwBHMEUCIQDGuOg7koEE\n" + + "H9K4VkSHaDD9rAndys2BtswdspfRKUFR3QIgVZ7QUX3H56ECuI8wsAkSjBze4lBO\n" + + "RgfN2xh3l9xQOK0wDQYJKoZIhvcNAQELBQADggIBAFQTTtyQSoV4Zq3QYMnb0yEp\n" + + "u6Hwic/wpYN5L0km+zZoHWuf58vfj8Yg/sfKmftGSZHDdc3NfYSVBlT/0Hl4SDhi\n" + + "zHLLyapoX2GNhbg3esu0Y1fch8E16z2A/wAwrFvxI0XrjHpOyDp4CBDYqDADNPiL\n" + + "vlEkiwP6r7WHjUdWRb7W0t75uAkcajn46XKpFmaHHie5KBch+KDGsUionuH5ZW8Y\n" + + "klh2B34uLWcGZuIR7PeCO9+91mbn/bBNeabGC70qMStaB139lp9P2M+l2WpyREUK\n" + + "l7qHwTsrlMmNb8n44zGtY4wL9NSYWTdTfhcU0FAPdPcLlnjoQubJ1O0vPkzfVYns\n" + + "WQrslxoCBor6CL6AYMQz3jbzQ0soD3Reb11+uTngWGJZtx4DT09RFB3a+1rcYjiS\n" + + "ijCBB+Lqx0xfLQnfBv1A0wjNqUY+gyEe0SpXqB4edqy5uaqawRRKMuNSnb2BVz0/\n" + + "keo1Kif/GSak+JUBpJ8hkJWygtrWCETUNfoseQhqo3gism0EGxJ04tBp+DRvfbrz\n" + + "X4aBgALRro3jSIR1Ibp+e0fxePwShy715SF2H4SfjvplTAKq5bwztZtQUkPR6fJ7\n" + + "5xT0f762c1yytKP1rHFMvzl6k7QWvC6zb2FeG5UqXJw3wFxxWsCuAUu5SPFfXdno\n" + + "5lIHTTV5rpZBN+PzTZsz\n" + + "-----END CERTIFICATE-----"; + + public static void main(String[] args) throws Exception { + + // Added to test for JDK-8256895 + System.setProperty("jdk.security.certpath.ocspNonce", "true"); + + // OCSP check by default + boolean ocspEnabled = args.length < 1 || !"CRL".equalsIgnoreCase(args[0]); + + ValidatePathWithParams pathValidator; + String[] validChainToValidate; + String[] revChainToValidate; + + if (!ocspEnabled) { + pathValidator = new ValidatePathWithParams(null); + pathValidator.enableCRLCheck(); + + validChainToValidate = new String[]{VALID, INT_CERTIGNA}; + revChainToValidate = new String[]{REVOKED, INT_CERTIGNA}; + } else { + // int certificate doesn't specify OCSP responder + pathValidator = new ValidatePathWithParams(new String[]{INT_CERTIGNA}); + pathValidator.enableOCSPCheck(); + + validChainToValidate = new String[]{VALID}; + revChainToValidate = new String[]{REVOKED}; + } + + // Validate valid + pathValidator.validate(validChainToValidate, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(revChainToValidate, + ValidatePathWithParams.Status.REVOKED, + "Fri Mar 10 03:39:51 PST 2023", System.out); + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,293 +0,0 @@ -/* - * 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 8245654 8314960 - * @summary Interoperability tests with Certigna Root CAs from Dhimyotis - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath CertignaRoots OCSP - * @run main/othervm -Djava.security.debug=certpath CertignaRoots CRL - */ - -/* - * Obtain TLS test artifacts for Certigna Root CAs from: - * - * Valid TLS Certificates: - * https://valid.servicesca.dhimyotis.com/ - * - * Revoked TLS Certificates: - * https://revoked.servicesca.dhimyotis.com/ - */ -public class CertignaRoots { - - // Owner: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, - // OU=0002 48146308100036, O=DHIMYOTIS, C=FR - // Issuer: CN=Certigna Root CA, OU=0002 48146308100036, O=Dhimyotis, C=FR - // Serial number: fd30cf04344fc38dd90c4e70753d0623 - // Valid from: Wed Nov 25 03:37:21 PST 2015 until: Fri Jun 03 04:37:21 PDT 2033 - private static final String INT_CERTIGNA_ROOT_CA = "-----BEGIN CERTIFICATE-----\n" + - "MIIHETCCBPmgAwIBAgIRAP0wzwQ0T8ON2QxOcHU9BiMwDQYJKoZIhvcNAQELBQAw\n" + - "WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw\n" + - "MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x\n" + - "NTExMjUxMTM3MjFaFw0zMzA2MDMxMTM3MjFaMH0xCzAJBgNVBAYTAkZSMRIwEAYD\n" + - "VQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxHTAb\n" + - "BgNVBGEMFE5UUkZSLTQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQQDDBRDZXJ0aWduYSBT\n" + - "ZXJ2aWNlcyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALPM+7Lp\n" + - "WBz9wFcPaTc3xnB+5g0XrnptB0EPPfrR04vO52Ykm4ky1d4ZLd10tbM1fa1RqNSO\n" + - "VWWg93O4pL7zCFKlz6JV74ZZVhHpEAwzBwv2oPnxvVbxtSN67xsSY66ahUYxjzs8\n" + - "+3FhmsiRxqwnTYvK2u70uglUvRisOKyTL/M6JnrC4y8tlmoz7OSa5BmBMVplJFQt\n" + - "vmON6N9aHLvYMz+EyJPCbXL6pELxeHjFT5QmIaRamsr2DOTaCjtBZKI1Wnh3X7ln\n" + - "bjM8MESJiV2t7E9tIQNG0Z/HI3tO4aaUMum3KysY5sC8v3vi7rryGidgzHQhrtP0\n" + - "ZXWW5UH/k7umLS/P/XXWnCFpc2Lxa1uDGfc2im7xibRoPP+JNZszN76euFlls6jy\n" + - "EXAiwnVr14tVVTewLK0OWs5SJHpEKp8PGMZRDj59EmMvokWwzL6QzNZ6vVAp00oO\n" + - "m05sbspNY9+MFqGKKUsKvhFGEa4XmRNxDe6KswLcjPZB+NKHZ0QWFd4ip5C5XmEK\n" + - "/8qIPjwVr9dah9+oiHGGO8Wx7gJAMF5DTmkvW7GhqCKj1LmHnabjzc8av6kxWVQZ\n" + - "i/C7HCm9i/W4wio+JA2EAFLqNL3GPNbK9kau4yPhQt/c7zxzo0OHnlsV4THCG7oO\n" + - "Cd3cfCiyfQcb3FBt6OSpaKRZxjCLBwP00r0fAgMBAAGjggGtMIIBqTASBgNVHRMB\n" + - "Af8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrOyGj0s3HLh/\n" + - "FxsZ0K7oTuM0XBIwHwYDVR0jBBgwFoAUGIdW4G537iQ1PE5zmh/W4eJ5fiswSQYD\n" + - "VR0gBEIwQDA+BgoqgXoBgTECAAEBMDAwLgYIKwYBBQUHAgEWImh0dHBzOi8vd3d3\n" + - "LmNlcnRpZ25hLmZyL2F1dG9yaXRlcy8wgYgGCCsGAQUFBwEBBHwwejA6BggrBgEF\n" + - "BQcwAoYuaHR0cDovL2F1dG9yaXRlLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNh\n" + - "LmRlcjA8BggrBgEFBQcwAoYwaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rpcy5jb20v\n" + - "Y2VydGlnbmFyb290Y2EuZGVyMG0GA1UdHwRmMGQwL6AtoCuGKWh0dHA6Ly9jcmwu\n" + - "Y2VydGlnbmEuZnIvY2VydGlnbmFyb290Y2EuY3JsMDGgL6AthitodHRwOi8vY3Js\n" + - "LmRoaW15b3Rpcy5jb20vY2VydGlnbmFyb290Y2EuY3JsMA0GCSqGSIb3DQEBCwUA\n" + - "A4ICAQCI5QbprXJ93L+JWHYpUTinXAMSvXMx2dmNm4mIiJRAbGnBOoEYx7M61fbL\n" + - "L5EJIYZhw8jLmeYVFuMao5OJLwda+RMmVzE7lyTGsY64IDKdwogByNCqbKzrlhnU\n" + - "8myyMNB0BDs2jgwQe2Dj9v+MddeHr7sDqvs7R1tSS5hoASLtdQhO7oxUzr3m7M8q\n" + - "+lh4jszli+cjfiPUVS2ADFu4ccQIh4OsIX6SWdU+8R+c/fn0FV6ip4SAVbNyCToz\n" + - "0ZbZKO8YTJgORxRmvrop9dPyuLWjaRrZ0LMx4a3EM3sQDPDqmsG0lHtfFj2PiJvq\n" + - "4lEYA+gDiLKODI+3DJMqo559m3QSS52DsShomHX/Txd0lJoZwepCE6X4KkG9FHjV\n" + - "WXyLgYFwCOcn+hkLhdpblms0wtjeSPITGOioSkefzhleJnDgJ9X4M3svd0HLTpJi\n" + - "lC1DmDZgdrXWITVdOoCogr2LFKNiGd0tbpKG533eKpfBALlm+afc6j73p1KhJEAn\n" + - "AfydDZqBRqv6+HHYplNDn/K2I1CZdkwaGrx3HOR/voGUi1sUI+hYbsPAFu8ZxrhD\n" + - "9UiysmLCfEUhqkbojony+L2mKsoLqyd24emQzn7GgMa7emlWX2jQUTwrD4SliZ2u\n" + - "OetVaZX5RLyqJWs4Igo/xye0xtMQN8INJ4hSZvnMQ1qFtuSRcQ==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, - // OU=0002 48146308100036, O=DHIMYOTIS, C=FR - // Issuer: CN=Certigna, O=Dhimyotis, C=FR - // Serial number: 6f82fa28acd6f784bb5b120ba87367ad - // Valid from: Wed Nov 25 03:33:52 PST 2015 until: Sat Nov 22 03:33:52 PST 2025 - private static final String INT_CERTIGNA = "-----BEGIN CERTIFICATE-----\n" + - "MIIGFjCCBP6gAwIBAgIQb4L6KKzW94S7WxILqHNnrTANBgkqhkiG9w0BAQsFADA0\n" + - "MQswCQYDVQQGEwJGUjESMBAGA1UECgwJRGhpbXlvdGlzMREwDwYDVQQDDAhDZXJ0\n" + - "aWduYTAeFw0xNTExMjUxMTMzNTJaFw0yNTExMjIxMTMzNTJaMH0xCzAJBgNVBAYT\n" + - "AkZSMRIwEAYDVQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgx\n" + - "MDAwMzYxHTAbBgNVBGEMFE5UUkZSLTQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQQDDBRD\n" + - "ZXJ0aWduYSBTZXJ2aWNlcyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n" + - "ggIBALPM+7LpWBz9wFcPaTc3xnB+5g0XrnptB0EPPfrR04vO52Ykm4ky1d4ZLd10\n" + - "tbM1fa1RqNSOVWWg93O4pL7zCFKlz6JV74ZZVhHpEAwzBwv2oPnxvVbxtSN67xsS\n" + - "Y66ahUYxjzs8+3FhmsiRxqwnTYvK2u70uglUvRisOKyTL/M6JnrC4y8tlmoz7OSa\n" + - "5BmBMVplJFQtvmON6N9aHLvYMz+EyJPCbXL6pELxeHjFT5QmIaRamsr2DOTaCjtB\n" + - "ZKI1Wnh3X7lnbjM8MESJiV2t7E9tIQNG0Z/HI3tO4aaUMum3KysY5sC8v3vi7rry\n" + - "GidgzHQhrtP0ZXWW5UH/k7umLS/P/XXWnCFpc2Lxa1uDGfc2im7xibRoPP+JNZsz\n" + - "N76euFlls6jyEXAiwnVr14tVVTewLK0OWs5SJHpEKp8PGMZRDj59EmMvokWwzL6Q\n" + - "zNZ6vVAp00oOm05sbspNY9+MFqGKKUsKvhFGEa4XmRNxDe6KswLcjPZB+NKHZ0QW\n" + - "Fd4ip5C5XmEK/8qIPjwVr9dah9+oiHGGO8Wx7gJAMF5DTmkvW7GhqCKj1LmHnabj\n" + - "zc8av6kxWVQZi/C7HCm9i/W4wio+JA2EAFLqNL3GPNbK9kau4yPhQt/c7zxzo0OH\n" + - "nlsV4THCG7oOCd3cfCiyfQcb3FBt6OSpaKRZxjCLBwP00r0fAgMBAAGjggHZMIIB\n" + - "1TASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU\n" + - "rOyGj0s3HLh/FxsZ0K7oTuM0XBIwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF\n" + - "9lo53BGhOKQ2MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAP\n" + - "BgNVBAMMCENlcnRpZ25hggkA/tzjAQ/JSP8wSQYDVR0gBEIwQDA+BgoqgXoBgTEB\n" + - "AAECMDAwLgYIKwYBBQUHAgEWImh0dHBzOi8vd3d3LmNlcnRpZ25hLmZyL2F1dG9y\n" + - "aXRlcy8wfAYIKwYBBQUHAQEEcDBuMDQGCCsGAQUFBzAChihodHRwOi8vYXV0b3Jp\n" + - "dGUuY2VydGlnbmEuZnIvY2VydGlnbmEuZGVyMDYGCCsGAQUFBzAChipodHRwOi8v\n" + - "YXV0b3JpdGUuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5kZXIwYQYDVR0fBFowWDAp\n" + - "oCegJYYjaHR0cDovL2NybC5jZXJ0aWduYS5mci9jZXJ0aWduYS5jcmwwK6ApoCeG\n" + - "JWh0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5jcmwwDQYJKoZIhvcN\n" + - "AQELBQADggEBAGLft7gIuGPZVfg0cTM+HT2xAZFPDb/2+siH06x+dH044zMKbBIN\n" + - "bRzhKipwB1A3MW8FQjveE9tyrfyuqZE/X+o2SlGcdNV44ybYkxo4f6kcLEavV/IW\n" + - "+oFEnojZlhpksYcxrvQoEyqkAwshe8IS2KtZHKVACrt+XSs0lwvy7ALGmHaF7A4b\n" + - "y6cZWItA7Lhj8XWp+8tBJDj7HocRbWtxzEODdBuyMgJzFrNjc+97J0vH/K0+3yjm\n" + - "kczpKshMA0tM+MF9XDMN/MuwrPmUWGO/fHiqHgUp8yqeWtl1n44ZxkkK1t9GRwhn\n" + - "DWLv73/xhTmdhWYQ/reo0GbgBoLiltKmIJQ=\n" + - "-----END CERTIFICATE-----"; - - // Owner: SERIALNUMBER=S266241169, CN=valid.servicesca.dhimyotis.com, O=DHIMYOTIS, - // L=VILLENEUVE D'ASCQ, C=FR - // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, OU=0002 - // 48146308100036, O=DHIMYOTIS, C=FR - // Serial number: c641ef7b0340c21515d8c462e729dc0e - // Valid from: Thu Mar 09 15:00:00 PST 2023 until: Mon Mar 11 15:59:59 PDT 2024 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIIdzCCBl+gAwIBAgIRAMZB73sDQMIVFdjEYucp3A4wDQYJKoZIhvcNAQELBQAw\n" + - "fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw\n" + - "MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx\n" + - "HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIzMDMwOTIzMDAwMFoX\n" + - "DTI0MDMxMTIyNTk1OVowezELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + - "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxJzAlBgNVBAMMHnZhbGlkLnNl\n" + - "cnZpY2VzY2EuZGhpbXlvdGlzLmNvbTETMBEGA1UEBRMKUzI2NjI0MTE2OTCCASIw\n" + - "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJDrFpZWEeBJoMUuG37wEmJ7XVeX\n" + - "Jde1bgURpFbLwifRj2TVmMdtfg9hXHL7B7Mh/+I8/e7kJz8mlU9qUYKyH24oAitE\n" + - "myXYHAKTydqTseiM3mp92n4PM+DrgsdbT7bpmiirNM0/sqWFNyGUz7kP6Z5E3uuU\n" + - "HSlzX1LBBj8S0ORNZWvomQho11gjuZJRS72X4XTnSc0DESwnLp2irUfx7pflBNt0\n" + - "sLE8BhpNSSQd91naJVKtCtn0H7df+o4gGBt2ZceCLBwU0NwN8+KXz06KjP8298V4\n" + - "P3+eR2QxAw4QBIanRaG6Gd4AmpdIaT7TpiYHotjrJ/Pbx5C8/cmgxxlmtI0CAwEA\n" + - "AaOCA/IwggPuMIHkBggrBgEFBQcBAQSB1zCB1DA2BggrBgEFBQcwAoYqaHR0cDov\n" + - "L2F1dG9yaXRlLmNlcnRpZ25hLmZyL3NlcnZpY2VzY2EuZGVyMDgGCCsGAQUFBzAC\n" + - "hixodHRwOi8vYXV0b3JpdGUuZGhpbXlvdGlzLmNvbS9zZXJ2aWNlc2NhLmRlcjAu\n" + - "BggrBgEFBQcwAYYiaHR0cDovL3NlcnZpY2VzY2Eub2NzcC5jZXJ0aWduYS5mcjAw\n" + - "BggrBgEFBQcwAYYkaHR0cDovL3NlcnZpY2VzY2Eub2NzcC5kaGlteW90aXMuY29t\n" + - "MB8GA1UdIwQYMBaAFKzsho9LNxy4fxcbGdCu6E7jNFwSMAkGA1UdEwQCMAAwYQYD\n" + - "VR0gBFowWDAIBgZngQwBAgIwTAYLKoF6AYExAgUBAQEwPTA7BggrBgEFBQcCARYv\n" + - "aHR0cHM6Ly93d3cuY2VydGlnbmEuY29tL2F1dG9yaXRlLWNlcnRpZmljYXRpb24w\n" + - "ZQYDVR0fBF4wXDAtoCugKYYnaHR0cDovL2NybC5kaGlteW90aXMuY29tL3NlcnZp\n" + - "Y2VzY2EuY3JsMCugKaAnhiVodHRwOi8vY3JsLmNlcnRpZ25hLmZyL3NlcnZpY2Vz\n" + - "Y2EuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIFoDBIBgNV\n" + - "HREEQTA/gh12YWxpZC5zZXJ2aWNlc2NhLmNlcnRpZ25hLmNvbYIedmFsaWQuc2Vy\n" + - "dmljZXNjYS5kaGlteW90aXMuY29tMB0GA1UdDgQWBBSzyYZfPBt65RUDq98+e0AK\n" + - "U8pd/jCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHcA7s3QZNXbGs7FXLedtM0T\n" + - "ojKHRny87N7DUUhZRnEftZsAAAGGy1ZNXwAABAMASDBGAiEAyG838/RfBOpojEI/\n" + - "cx++f0tvuDbc/rVa0WNcd2f9HekCIQDVKV2wI3VkD3wNmO93m022H7kvKD1OBEhw\n" + - "Tn6+0ZLA6QB2AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABhstW\n" + - "TcYAAAQDAEcwRQIhAOuj/r5G1wHNgFOMg3jsr3uWmWzIIkTmwmp4hJqvsJzzAiBf\n" + - "nm/jZCUW8DFY+iC+O/+Hzsk/kVDkKIlBDd6rA3MzJgB2AFWB1MIWkDYBSuoLm1c8\n" + - "U/DA5Dh4cCUIFy+jqh0HE9MMAAABhstWTw4AAAQDAEcwRQIgRbCAqI1/nxc6P4de\n" + - "Fqg/zc1+ldMDWjeamWjhctciGsgCIQDHQ4OKj0AA7hQKFIe1SVp+00BxRefFGmq7\n" + - "ZJ+8q+pRqzANBgkqhkiG9w0BAQsFAAOCAgEAVkzCC9LIHU+iOi+GFeCtWxxa5Fsk\n" + - "5gXnDJmtbdoVe2TJvOhrb+VnNI7/Ak+csBv3vxNl3P3DXIbPryB98aelleX7pkfP\n" + - "PcKhFAlbwzbII2D3L0mjFLERtVwdnoEJXXKcHsb9hJResKipZ//daMPD8FthHvEE\n" + - "HmtOrR0lHLjhbi4ODq0e4xyygbxFXXl5CCjtBw0jBtZaMDQaC3eemK9LkOggLz3h\n" + - "qs/+VQ7RyKfcKCuGC5Wb4GJR+IDKH812hFsUWmXe26MPoyTrzLNq6tfQZHSuY5Hj\n" + - "K0ZwldEkUZ2Hd7PrRlhCiGdVCp/2kS2yefhUkvX7Z5K5wX6n+LylfzOTvWf6ZPwQ\n" + - "1jTI0Js8ig4eHF25GlqgOWrqbyF9j67kLs3f7/c5Kx3FlclJ7/vlL8zEcTmGU7rm\n" + - "ZFOhEMDT/UYkitqAOvrgT60oIm9YJ1XTAVTeDbW0FFAb2nFmeBOrw8N3jaCb+jpO\n" + - "ysBA/lDaGTiQhMlJK44vwgS+TjbeWHxvmAE5srKa7MWU8Mmku2vuX95lupJo4LmD\n" + - "zOsihH00hyhtHFUB1TGXuaf77kFsipE6iycyxpcrpJ1UAWiZrba6PAZ85TbYhEdY\n" + - "FDNm7F7CVPU67HV5gE2kDa3Jprd1SjwO095LsRptWhzxUByhee3JI0jljBTaKowy\n" + - "jPv8oekm7zqCLzY=\n" + - "-----END CERTIFICATE-----"; - - // Owner: SERIALNUMBER=S266251168, CN=revoked.servicesca.certigna.com, O=DHIMYOTIS, - // L=VILLENEUVE D'ASCQ, C=FR - // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, OU=0002 - // 48146308100036, O=DHIMYOTIS, C=FR - // Serial number: e863f752a23a735e3ccf958abf18565b - // Valid from: Thu Mar 09 15:00:00 PST 2023 until: Fri Mar 08 14:59:59 PST 2024 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIIezCCBmOgAwIBAgIRAOhj91KiOnNePM+Vir8YVlswDQYJKoZIhvcNAQELBQAw\n" + - "fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw\n" + - "MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx\n" + - "HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIzMDMwOTIzMDAwMFoX\n" + - "DTI0MDMwODIyNTk1OVowfDELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + - "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxKDAmBgNVBAMMH3Jldm9rZWQu\n" + - "c2VydmljZXNjYS5jZXJ0aWduYS5jb20xEzARBgNVBAUTClMyNjYyNTExNjgwggEi\n" + - "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCBqKNjMkHqJ9EQa3CjuZ6EYMz6\n" + - "mWODrEucRcJDihYMigaV1oRyquGlFQ82ootXaK5bU+EYSMmUwbRpdZ9G/oZUn2+K\n" + - "MKAFDI+MoZoFhQC+2w0AzJycCf/hShUVxcRREKRKdfzv+k5YHj3e8ic16tGlTFXT\n" + - "IF1x3y2Uru7mzZARsZJqnRqaqPPghT/QlBpcA04yLi3iSpgO++mRrJxTUoUHlDw/\n" + - "a1nhqnDgH2yKN7tSfwFTetnXat6/UVt0CJ/6dJF6oY8bGWO1YB03Xdq735eLdJE4\n" + - "t38pV/X8rf5Mc9ZQh8IGrjVW83M8mQmqaX5rbsOl0ZCA/q6RWxRFEF2SwK+dAgMB\n" + - "AAGjggP1MIID8TCB5AYIKwYBBQUHAQEEgdcwgdQwNgYIKwYBBQUHMAKGKmh0dHA6\n" + - "Ly9hdXRvcml0ZS5jZXJ0aWduYS5mci9zZXJ2aWNlc2NhLmRlcjA4BggrBgEFBQcw\n" + - "AoYsaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rpcy5jb20vc2VydmljZXNjYS5kZXIw\n" + - "LgYIKwYBBQUHMAGGImh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuY2VydGlnbmEuZnIw\n" + - "MAYIKwYBBQUHMAGGJGh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuZGhpbXlvdGlzLmNv\n" + - "bTAfBgNVHSMEGDAWgBSs7IaPSzccuH8XGxnQruhO4zRcEjAJBgNVHRMEAjAAMGEG\n" + - "A1UdIARaMFgwCAYGZ4EMAQICMEwGCyqBegGBMQIFAQEBMD0wOwYIKwYBBQUHAgEW\n" + - "L2h0dHBzOi8vd3d3LmNlcnRpZ25hLmNvbS9hdXRvcml0ZS1jZXJ0aWZpY2F0aW9u\n" + - "MGUGA1UdHwReMFwwLaAroCmGJ2h0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9zZXJ2\n" + - "aWNlc2NhLmNybDAroCmgJ4YlaHR0cDovL2NybC5jZXJ0aWduYS5mci9zZXJ2aWNl\n" + - "c2NhLmNybDATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBaAwTAYD\n" + - "VR0RBEUwQ4IgcmV2b2tlZC5zZXJ2aWNlc2NhLmRoaW15b3Rpcy5jb22CH3Jldm9r\n" + - "ZWQuc2VydmljZXNjYS5jZXJ0aWduYS5jb20wHQYDVR0OBBYEFEQsKyX8x8zVxVC2\n" + - "HEK7+bOBLoMkMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVc\n" + - "t520zROiModGfLzs3sNRSFlGcR+1mwAAAYbLTxPnAAAEAwBHMEUCIQD16IHX+8+4\n" + - "zWnxIME4rzCgQIA4m5OsEqP6ssgRG5iurwIgdBOGFGlF6+DGPSm5FKuk5ShAA8ZC\n" + - "AE+E27CKLkBTnfgAdgB2/4g/Crb7lVHCYcz1h7o0tKTNuyncaEIKn+ZnTFo6dAAA\n" + - "AYbLTxRMAAAEAwBHMEUCIDmW9elysDm3zAeIXsgJwmL33EoMTyVhA3ah2jkvMjzv\n" + - "AiEA6aIZXtwk2DnFt+GA6gLr4UgswUCuK4wxheDVwbpSw/4AdgA7U3d1Pi25gE6L\n" + - "MFsG/kA7Z9hPw/THvQANLXJv4frUFwAAAYbLTxXAAAAEAwBHMEUCIQDGuOg7koEE\n" + - "H9K4VkSHaDD9rAndys2BtswdspfRKUFR3QIgVZ7QUX3H56ECuI8wsAkSjBze4lBO\n" + - "RgfN2xh3l9xQOK0wDQYJKoZIhvcNAQELBQADggIBAFQTTtyQSoV4Zq3QYMnb0yEp\n" + - "u6Hwic/wpYN5L0km+zZoHWuf58vfj8Yg/sfKmftGSZHDdc3NfYSVBlT/0Hl4SDhi\n" + - "zHLLyapoX2GNhbg3esu0Y1fch8E16z2A/wAwrFvxI0XrjHpOyDp4CBDYqDADNPiL\n" + - "vlEkiwP6r7WHjUdWRb7W0t75uAkcajn46XKpFmaHHie5KBch+KDGsUionuH5ZW8Y\n" + - "klh2B34uLWcGZuIR7PeCO9+91mbn/bBNeabGC70qMStaB139lp9P2M+l2WpyREUK\n" + - "l7qHwTsrlMmNb8n44zGtY4wL9NSYWTdTfhcU0FAPdPcLlnjoQubJ1O0vPkzfVYns\n" + - "WQrslxoCBor6CL6AYMQz3jbzQ0soD3Reb11+uTngWGJZtx4DT09RFB3a+1rcYjiS\n" + - "ijCBB+Lqx0xfLQnfBv1A0wjNqUY+gyEe0SpXqB4edqy5uaqawRRKMuNSnb2BVz0/\n" + - "keo1Kif/GSak+JUBpJ8hkJWygtrWCETUNfoseQhqo3gism0EGxJ04tBp+DRvfbrz\n" + - "X4aBgALRro3jSIR1Ibp+e0fxePwShy715SF2H4SfjvplTAKq5bwztZtQUkPR6fJ7\n" + - "5xT0f762c1yytKP1rHFMvzl6k7QWvC6zb2FeG5UqXJw3wFxxWsCuAUu5SPFfXdno\n" + - "5lIHTTV5rpZBN+PzTZsz\n" + - "-----END CERTIFICATE-----"; - - public static void main(String[] args) throws Exception { - // OCSP check by default - boolean ocspEnabled = args.length < 1 || !"CRL".equalsIgnoreCase(args[0]); - - // CN=Certigna - new CertignaCAs().runTest(ocspEnabled, - VALID, - REVOKED, - INT_CERTIGNA); - - // CN=Certigna Root CA - new CertignaCAs().runTest(ocspEnabled, - VALID, - REVOKED, - INT_CERTIGNA_ROOT_CA); - } -} - -class CertignaCAs { - public void runTest(boolean ocspEnabled, - final String VALID, - final String REVOKED, - final String INT_CERT) throws Exception { - - ValidatePathWithParams pathValidator; - String[] validChainToValidate; - String[] revChainToValidate; - - if (!ocspEnabled) { - pathValidator = new ValidatePathWithParams(null); - pathValidator.enableCRLCheck(); - - validChainToValidate = new String[]{VALID, INT_CERT}; - revChainToValidate = new String[]{REVOKED, INT_CERT}; - } else { - // int certificate doesn't specify OCSP responder - pathValidator = new ValidatePathWithParams(new String[]{INT_CERT}); - pathValidator.enableOCSPCheck(); - - validChainToValidate = new String[]{VALID}; - revChainToValidate = new String[]{REVOKED}; - } - - // Validate valid - pathValidator.validate(validChainToValidate, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(revChainToValidate, - ValidatePathWithParams.Status.REVOKED, - "Fri Mar 10 03:39:51 PST 2023", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,643 +0,0 @@ -/* - * Copyright (c) 2017, 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. - */ - - /* - * @test - * @bug 8189131 8231887 - * @summary Interoperability tests with Comodo RSA, ECC, userTrust RSA, and - * userTrust ECC CAs - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath ComodoCA OCSP - * @run main/othervm -Djava.security.debug=certpath ComodoCA CRL - */ - - /* - * Obtain TLS test artifacts for Comodo CAs from: - * - * Valid TLS Certificates: - * https://comodorsacertificationauthority-ev.comodoca.com - * https://comodoecccertificationauthority-ev.comodoca.com - * https://usertrustrsacertificationauthority-ev.comodoca.com - * https://usertrustecccertificationauthority-ev.comodoca.com - * - * Revoked TLS Certificates: - * https://comodorsacertificationauthority-ev.comodoca.com:444 - * https://comodoecccertificationauthority-ev.comodoca.com:444 - * https://usertrustrsacertificationauthority-ev.comodoca.com:444 - * https://usertrustecccertificationauthority-ev.comodoca.com:444 - */ -public class ComodoCA { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - new ComodoRSA().runTest(pathValidator); - new ComodoECC().runTest(pathValidator); - new ComodoUserTrustRSA().runTest(pathValidator); - new ComodoUserTrustECC().runTest(pathValidator); - } -} - -class ComodoRSA { - - // Owner: CN=COMODO RSA Extended Validation Secure Server CA, - // O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB - // Issuer: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, - // L=Salford, ST=Greater Manchester, C=GB - // Serial number: 6a74380d4ebfed435b5a3f7e16abdd8 - // Valid from: Sat Feb 11 16:00:00 PST 2012 until: Thu Feb 11 15:59:59 PST 2027 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" - + "MIIGDjCCA/agAwIBAgIQBqdDgNTr/tQ1taP34Wq92DANBgkqhkiG9w0BAQwFADCB\n" - + "hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" - + "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\n" - + "BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTIwMjEy\n" - + "MDAwMDAwWhcNMjcwMjExMjM1OTU5WjCBkjELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\n" - + "EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\n" - + "Q09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMTL0NPTU9ETyBSU0EgRXh0ZW5kZWQg\n" - + "VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" - + "AQ8AMIIBCgKCAQEAlVbeVLTf1QJJe9FbXKKyHo+cK2JMK40SKPMalaPGEP0p3uGf\n" - + "CzhAk9HvbpUQ/OGQF3cs7nU+e2PsYZJuTzurgElr3wDqAwB/L3XVKC/sVmePgIOj\n" - + "vdwDmZOLlJFWW6G4ajo/Br0OksxgnP214J9mMF/b5pTwlWqvyIqvgNnmiDkBfBzA\n" - + "xSr3e5Wg8narbZtyOTDr0VdVAZ1YEZ18bYSPSeidCfw8/QpKdhQhXBZzQCMZdMO6\n" - + "WAqmli7eNuWf0MLw4eDBYuPCGEUZUaoXHugjddTI0JYT/8ck0YwLJ66eetw6YWNg\n" - + "iJctXQUL5Tvrrs46R3N2qPos3cCHF+msMJn4HwIDAQABo4IBaTCCAWUwHwYDVR0j\n" - + "BBgwFoAUu69+Aj36pvE8hI6t7jiY7NkyMtQwHQYDVR0OBBYEFDna/8ooFIqodBMI\n" - + "ueQOqdL6fp1pMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMD4G\n" - + "A1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5j\n" - + "b21vZG8uY29tL0NQUzBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9k\n" - + "b2NhLmNvbS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggr\n" - + "BgEFBQcBAQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29t\n" - + "L0NPTU9ET1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz\n" - + "cC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAERCnUFRK0iIXZebeV4R\n" - + "AUpSGXtBLMeJPNBy3IX6WK/VJeQT+FhlZ58N/1eLqYVeyqZLsKeyLeCMIs37/3mk\n" - + "jCuN/gI9JN6pXV/kD0fQ22YlPodHDK4ixVAihNftSlka9pOlk7DgG4HyVsTIEFPk\n" - + "1Hax0VtpS3ey4E/EhOfUoFDuPPpE/NBXueEoU/1Tzdy5H3pAvTA/2GzS8+cHnx8i\n" - + "teoiccsq8FZ8/qyo0QYPFBRSTP5kKwxpKrgNUG4+BAe/eiCL+O5lCeHHSQgyPQ0o\n" - + "fkkdt0rvAucNgBfIXOBhYsvss2B5JdoaZXOcOBCgJjqwyBZ9kzEi7nQLiMBciUEA\n" - + "KKlHMd99SUWa9eanRRrSjhMQ34Ovmw2tfn6dNVA0BM7pINae253UqNpktNEvWS5e\n" - + "ojZh1CSggjMziqHRbO9haKPl0latxf1eYusVqHQSTC8xjOnB3xBLAer2VBvNfzu9\n" - + "XJ/B288ByvK6YBIhMe2pZLiySVgXbVrXzYxtvp5/4gJYp9vDLVj2dAZqmvZh+fYA\n" - + "tmnYOosxWd2R5nwnI4fdAw+PKowegwFOAWEMUnNt/AiiuSpm5HZNMaBWm9lTjaK2\n" - + "jwLI5jqmBNFI+8NKAnb9L9K8E7bobTQk+p0pisehKxTxlgBzuRPpwLk6R1YCcYAn\n" - + "pLwltum95OmYdBbxN4SBB7SC\n" - + "-----END CERTIFICATE-----"; - - // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, - // O=Sectigo Limited, STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, - // L=Salford, ST=Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, - // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: 9eb246629030e0b527ca2f93e5ebf25a - // Valid from: Mon Mar 01 16:00:00 PST 2021 until: Sat Apr 02 16:59:59 PDT 2022 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHSzCCBjOgAwIBAgIRAJ6yRmKQMOC1J8ovk+Xr8lowDQYJKoZIhvcNAQELBQAw\n" + - "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" + - "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" + - "VQQDEy9DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" + - "ciBDQTAeFw0yMTAzMDIwMDAwMDBaFw0yMjA0MDIyMzU5NTlaMIIBNzERMA8GA1UE\n" + - "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" + - "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRMw\n" + - "EQYDVQQIEwpNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRYwFAYDVQQJEw1U\n" + - "cmFmZm9yZCBSb2FkMRYwFAYDVQQJEw1FeGNoYW5nZSBRdWF5MSUwIwYDVQQJExwz\n" + - "cmQgRmxvb3IsIDI2IE9mZmljZSBWaWxsYWdlMRgwFgYDVQQKEw9TZWN0aWdvIExp\n" + - "bWl0ZWQxODA2BgNVBAMTL2NvbW9kb3JzYWNlcnRpZmljYXRpb25hdXRob3JpdHkt\n" + - "ZXYuY29tb2RvY2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + - "0P95lAFOOkEOy614rCX7OlOK0Xy0nPAcCFxAcLYBosX8YmXWuePHg596UyEqE3U5\n" + - "30pTqiccY53bDiYPgSJgr1OlfC7BPLN+QKaeSrFmNgrcoAk3TXejgv7zLXOwZVS6\n" + - "Wk38Z8xrFNvhd2Z5J6RM/3U+HDfF7OKMGrexr77Ws7lEFpPUgd4eEe+IL1Y2sbwI\n" + - "iD+PkzIL2LjctkeJFcsRHUvNP8wIhGyIbkARuJhdXkE13lKKIe0EnWrRkkf4DEvY\n" + - "RFpPjVUKmluhnBOGYkYaiTL0VaOnrPxToSfHR8Awkhk0TNbosAkUo8TKcRTTTiMU\n" + - "UIS6Y9SqoILiiDG6WmFjzQIDAQABo4IC8jCCAu4wHwYDVR0jBBgwFoAUOdr/yigU\n" + - "iqh0Ewi55A6p0vp+nWkwHQYDVR0OBBYEFD5LhmEivA6h4az0EFPi5erz1TH+MA4G\n" + - "A1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMB\n" + - "BggrBgEFBQcDAjBJBgNVHSAEQjBAMDUGDCsGAQQBsjEBAgEFATAlMCMGCCsGAQUF\n" + - "BwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBN\n" + - "MEugSaBHhkVodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FFeHRlbmRl\n" + - "ZFZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYcGCCsGAQUFBwEBBHsweTBR\n" + - "BggrBgEFBQcwAoZFaHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPUlNBRXh0\n" + - "ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCQGCCsGAQUFBzABhhho\n" + - "dHRwOi8vb2NzcC5jb21vZG9jYS5jb20wOgYDVR0RBDMwMYIvY29tb2RvcnNhY2Vy\n" + - "dGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggEEBgorBgEEAdZ5\n" + - "AgQCBIH1BIHyAPAAdgBGpVXrdfqRIDC1oolp9PN9ESxBdL79SbiFq/L8cP5tRwAA\n" + - "AXfyqEfyAAAEAwBHMEUCIQDJbHPgbqK21/Nugwl5mgMO81YQSHOm4VcQ8UvOJjnN\n" + - "JQIgWw9fortwJBtv2Mts6xJYr5D6itPpEYP8uegURneBwRsAdgBvU3asMfAxGdiZ\n" + - "AKRRFf93FRwR2QLBACkGjbIImjfZEwAAAXfyqEjyAAAEAwBHMEUCIDifAsuw37D4\n" + - "beHZ9Ed5/Pab0Eg6Cobrh4jv3bjfA6KIAiEAmiA/XD+AccfI85c+C2zH9wNIs+Zm\n" + - "/V/uo/sv0i9eCAYwDQYJKoZIhvcNAQELBQADggEBADRFnOFgb3mzCUpXxiU5/mM5\n" + - "ECRj3NzXKXjcYlSMhVcWA7Eqa5rhJuh11vbPoDQzQcGxntS/zhRwJFRF3hnyFa3m\n" + - "4t+7ZnUaJN+GOMTABh4kYiOSpE9id12URdJzWv2IHg4CU3OLnsBHGh7H9eWfbPvn\n" + - "OW4owV1ChpiEHh40i/NQkTn9JzjlZepI9+EsSdhn2tpis7tko6PX/plgw8bRgm7f\n" + - "ong2QaX/DE6z4VIdomW8TQhB9turhKxwjzPTbtYDQIgZfRP/H1S5jYutqbE5yL5B\n" + - "r+VOiSuB8234P4xWg1IBL2EFbxPdgOSMTWRJutUcj44kJKmwp5GUQtySSccw4gk=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, - // O=Sectigo Limited, STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, - // L=Salford, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, - // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: a0c7cabcc25ed9358ded02cc1d485545 - // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIH0TCCBrmgAwIBAgIRAKDHyrzCXtk1je0CzB1IVUUwDQYJKoZIhvcNAQELBQAw\n" + - "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" + - "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" + - "VQQDEy9DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" + - "ciBDQTAeFw0xOTA5MzAwMDAwMDBaFw0yMTEyMjgyMzU5NTlaMIIBPjERMA8GA1UE\n" + - "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" + - "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRAw\n" + - "DgYDVQQHEwdTYWxmb3JkMRYwFAYDVQQJEw1UcmFmZm9yZCBSb2FkMRYwFAYDVQQJ\n" + - "Ew1FeGNoYW5nZSBRdWF5MSUwIwYDVQQJExwzcmQgRmxvb3IsIDI2IE9mZmljZSBW\n" + - "aWxsYWdlMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxGjAYBgNVBAsTEUNPTU9E\n" + - "TyBFViBTR0MgU1NMMTgwNgYDVQQDEy9jb21vZG9yc2FjZXJ0aWZpY2F0aW9uYXV0\n" + - "aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n" + - "AQoCggEBAND/eZQBTjpBDsuteKwl+zpTitF8tJzwHAhcQHC2AaLF/GJl1rnjx4Of\n" + - "elMhKhN1Od9KU6onHGOd2w4mD4EiYK9TpXwuwTyzfkCmnkqxZjYK3KAJN013o4L+\n" + - "8y1zsGVUulpN/GfMaxTb4XdmeSekTP91Phw3xezijBq3sa++1rO5RBaT1IHeHhHv\n" + - "iC9WNrG8CIg/j5MyC9i43LZHiRXLER1LzT/MCIRsiG5AEbiYXV5BNd5SiiHtBJ1q\n" + - "0ZJH+AxL2ERaT41VCppboZwThmJGGoky9FWjp6z8U6Enx0fAMJIZNEzW6LAJFKPE\n" + - "ynEU004jFFCEumPUqqCC4ogxulphY80CAwEAAaOCA3EwggNtMB8GA1UdIwQYMBaA\n" + - "FDna/8ooFIqodBMIueQOqdL6fp1pMB0GA1UdDgQWBBQ+S4ZhIrwOoeGs9BBT4uXq\n" + - "89Ux/jAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggr\n" + - "BgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA7BgwrBgEEAbIxAQIBBQEwKzAp\n" + - "BggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwBwYFZ4EM\n" + - "AQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09N\n" + - "T0RPUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGHBggr\n" + - "BgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2EuY29t\n" + - "L0NPTU9ET1JTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAk\n" + - "BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMDoGA1UdEQQzMDGC\n" + - "L2NvbW9kb3JzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29t\n" + - "MIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdQDuS723dc5guuFCaR+r4Z5mow9+\n" + - "X7By2IMAxHuJeqj9ywAAAW2DAXefAAAEAwBGMEQCIDqP1einOiPHnaG1fOZMDrEc\n" + - "RAxjq3vEl94fp4pkmke7AiBsJOvPE6irgcOO1/lnP7NRuln7iPJjU7T20PEK5/rm\n" + - "KwB2AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYMBd0kAAAQD\n" + - "AEcwRQIhALgUI5XxM1NHbJDdr19h2pe3LhzK4tpuB/OQ9BgCyrGXAiBdr6mNCB/G\n" + - "rbdVx0u7iezwC7mq7iaWugR3rrWlSA8fWQB2ALvZ37wfinG1k5Qjl6qSe0c4V5UK\n" + - "q1LoGpCWZDaOHtGFAAABbYMBd1oAAAQDAEcwRQIgXbG32dagMeLhuZb+LSpJO1vI\n" + - "BmxmRnNdiz5FbG9cCbwCIQCr1X9f+ebT5fhlDUNBURUorTtM8QQciBiueBqvHk7+\n" + - "1DANBgkqhkiG9w0BAQsFAAOCAQEAM/A/1dgoc5NP1n+w3SX9qWcN7QT7ExdrnZSl\n" + - "Ygn0PF2fx4gz7cvNKucbpQJNA4C9awGydyYK8/o5KDUXt3K7eb1OAZ/NZBjygsJs\n" + - "ikXvxlBh8oEoqBOfOtr24l0NGUWnP8Qeu/VPcIMER4V8qX+in0pCXkSd67nkp6Bs\n" + - "EcqhDPgmzdSC1gQHsZuBdotG14OfdH1cG1bRK6GadISLG1h8BFukVem42B149v8F\n" + - "MCIUQAYprAVv2WlTZKBx9XzuK6IK3+klHZ07Jfvjvt7PPG5HKSMWBMnMaTHKcyQI\n" + - "G3t91yw7BnNNInZlBSsFtqjbHhDcr7uruZdbi0rerSsi2qDr0w==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Tue Mar 02 02:51:39 PST 2021", System.out); - } -} - -class ComodoECC { - - // Owner: CN=COMODO ECC Extended Validation Secure Server CA, - // O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB - // Issuer: CN=COMODO ECC Certification Authority, O=COMODO CA Limited, - // L=Salford, ST=Greater Manchester, C=GB - // Serial number: 61d4643b412b5d8d715499d8553aa03 - // Valid from: Sun Apr 14 17:00:00 PDT 2013 until: Fri Apr 14 16:59:59 PDT 2028 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" - + "MIIDojCCAyigAwIBAgIQBh1GQ7QStdjXFUmdhVOqAzAKBggqhkjOPQQDAzCBhTEL\n" - + "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" - + "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT\n" - + "IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTMwNDE1MDAw\n" - + "MDAwWhcNMjgwNDE0MjM1OTU5WjCBkjELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy\n" - + "ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N\n" - + "T0RPIENBIExpbWl0ZWQxODA2BgNVBAMTL0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFs\n" - + "aWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" - + "QgAEV3AaPyeTQy0aWXXkBJMR42DsJ5pnbliJe7ndaHzCDslVlY8ofpxeFiqluZrK\n" - + "KNcJeBU/Jl1YI9jLMyMZKsfSoaOCAWkwggFlMB8GA1UdIwQYMBaAFHVxpxlIGbyd\n" - + "nepBR9+UxEh3mdN5MB0GA1UdDgQWBBTTTsMZulhZ0Rxgt2FTRzund4/4ijAOBgNV\n" - + "HQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADA+BgNVHSAENzA1MDMGBFUd\n" - + "IAAwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMw\n" - + "TAYDVR0fBEUwQzBBoD+gPYY7aHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RP\n" - + "RUNDQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwcQYIKwYBBQUHAQEEZTBjMDsG\n" - + "CCsGAQUFBzAChi9odHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9DT01PRE9FQ0NBZGRU\n" - + "cnVzdENBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29t\n" - + "MAoGCCqGSM49BAMDA2gAMGUCMQDmPWS98nREWdt4xB83r9MVvgG5INpKHi6V1dUY\n" - + "lCqvSvXXjK0QvZSrOB7cj9RavGgCMG2xJNG+SvlTWEYpmK7eXSgmRUgoBDeQ0yDK\n" - + "lnxmeeOBnnCaDIxAcA3aCj2Gtdt3sA==\n" - + "-----END CERTIFICATE-----"; - - // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, O=Sectigo Limited, STREET="3rd Floor, - // 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, ST=Manchester, OID.2.5.4.17=M5 3EQ, - // C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: db437a31e5be29a62443e3caa1479001 - // Valid from: Mon Mar 01 16:00:00 PST 2021 until: Sat Apr 02 16:59:59 PDT 2022 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFvzCCBWWgAwIBAgIRANtDejHlvimmJEPjyqFHkAEwCgYIKoZIzj0EAwIwgZIx\n" + - "CzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNV\n" + - "BAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYDVQQD\n" + - "Ey9DT01PRE8gRUNDIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD\n" + - "QTAeFw0yMTAzMDIwMDAwMDBaFw0yMjA0MDIyMzU5NTlaMIIBNzERMA8GA1UEBRMI\n" + - "MDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZhdGUg\n" + - "T3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRMwEQYD\n" + - "VQQIEwpNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRYwFAYDVQQJEw1UcmFm\n" + - "Zm9yZCBSb2FkMRYwFAYDVQQJEw1FeGNoYW5nZSBRdWF5MSUwIwYDVQQJExwzcmQg\n" + - "Rmxvb3IsIDI2IE9mZmljZSBWaWxsYWdlMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0\n" + - "ZWQxODA2BgNVBAMTL2NvbW9kb2VjY2NlcnRpZmljYXRpb25hdXRob3JpdHktZXYu\n" + - "Y29tb2RvY2EuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt26qBS7TRu/y\n" + - "fR+RiqLAzW2C+UspFZlORc4EhLfNYMgFkoZKjEnwJzudH6a+uRPqPOhPgUd6PFfR\n" + - "QFOcLjmhgaOCAvIwggLuMB8GA1UdIwQYMBaAFNNOwxm6WFnRHGC3YVNHO6d3j/iK\n" + - "MB0GA1UdDgQWBBTpZ0tzKscFw6Z3vCEDFzGR5VSkVzAOBgNVHQ8BAf8EBAMCBYAw\n" + - "DAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwSQYD\n" + - "VR0gBEIwQDA1BgwrBgEEAbIxAQIBBQEwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9z\n" + - "ZWN0aWdvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov\n" + - "L2NybC5jb21vZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRWYWxpZGF0aW9uU2Vj\n" + - "dXJlU2VydmVyQ0EuY3JsMIGHBggrBgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0\n" + - "dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET0VDQ0V4dGVuZGVkVmFsaWRhdGlv\n" + - "blNlY3VyZVNlcnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29t\n" + - "b2RvY2EuY29tMDoGA1UdEQQzMDGCL2NvbW9kb2VjY2NlcnRpZmljYXRpb25hdXRo\n" + - "b3JpdHktZXYuY29tb2RvY2EuY29tMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYA\n" + - "RqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy/HD+bUcAAAF38qtH4AAABAMARzBF\n" + - "AiBsKoB1TTfoUYUNqF160/vlOENHyK1zzARcnfGKYURHTwIhANKYWg1CO7jyCPk+\n" + - "IrrLaR+461snNK4LJZXJm4o/9GeeAHYAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQAp\n" + - "Bo2yCJo32RMAAAF38qtJIAAABAMARzBFAiEA1hgxkYZb5Tc9+vQsDnsfXVewClN2\n" + - "7gzwd4hZdqAsOSYCID9CWcBvkKrL44mfe9ky1Z6BnAWHUBMCxTjt8MO/IMZ8MAoG\n" + - "CCqGSM49BAMCA0gAMEUCIBa3sfOiVb0q4LcXU9umKjzVw3Ib8VdiPTtXSnyl0oLb\n" + - "AiEAnpRB53UtLAF7xw98ELmK/LEk1b5KSlqoO8sFHgwQ8vI=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=Sectigo Limited, - // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, OID.2.5.4.17=M5 3EQ, - // C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: 7972d9d8472a2d52ad1ee6edfb16cbe1 - // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGPzCCBeWgAwIBAgIQeXLZ2EcqLVKtHubt+xbL4TAKBggqhkjOPQQDAjCBkjEL\n" + - "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" + - "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" + - "L0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" + - "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggE6MREwDwYDVQQFEwgw\n" + - "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" + - "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" + - "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" + - "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" + - "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEWMBQGA1UECxMNQ09NT0RPIEVW\n" + - "IFNTTDE4MDYGA1UEAxMvY29tb2RvZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1l\n" + - "di5jb21vZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS3bqoFLtNG\n" + - "7/J9H5GKosDNbYL5SykVmU5FzgSEt81gyAWShkqMSfAnO50fpr65E+o86E+BR3o8\n" + - "V9FAU5wuOaGBo4IDcDCCA2wwHwYDVR0jBBgwFoAU007DGbpYWdEcYLdhU0c7p3eP\n" + - "+IowHQYDVR0OBBYEFOlnS3MqxwXDpne8IQMXMZHlVKRXMA4GA1UdDwEB/wQEAwIF\n" + - "gDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBP\n" + - "BgNVHSAESDBGMDsGDCsGAQQBsjEBAgEFATArMCkGCCsGAQUFBwIBFh1odHRwczov\n" + - "L3NlY3VyZS5jb21vZG8uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBH\n" + - "hkVodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9FQ0NFeHRlbmRlZFZhbGlk\n" + - "YXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYcGCCsGAQUFBwEBBHsweTBRBggrBgEF\n" + - "BQcwAoZFaHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRW\n" + - "YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8v\n" + - "b2NzcC5jb21vZG9jYS5jb20wOgYDVR0RBDMwMYIvY29tb2RvZWNjY2VydGlmaWNh\n" + - "dGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF8BgorBgEEAdZ5AgQCBIIB\n" + - "bASCAWgBZgB1AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABbYME\n" + - "EzgAAAQDAEYwRAIgbdo71lBleuJiq+D0ZLp51oVUyWD9EyrtgBSCNwIW4cMCIAqg\n" + - "0VFTWHEmAVjaV23fGj3Ybu3mpSiHr6viGlgA2lYaAHUAVYHUwhaQNgFK6gubVzxT\n" + - "8MDkOHhwJQgXL6OqHQcT0wwAAAFtgwQTKAAABAMARjBEAiBb/gW1RU7kgFBiNpHx\n" + - "LStujKIocyENUTXsMbsac+LktwIgXbEr8vOOCEdBdXQ2F/FKec8ft6gz57mHNmwl\n" + - "pp7phbQAdgC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DBBM6\n" + - "AAAEAwBHMEUCIQDjKN3h86ofR94+JxLFoYuoA+DRtxEY8XGg+NQXlZfUrgIgEoO2\n" + - "ZzKbGfohdwj/WtDwJDRX5pjXF4M0nECiwtYXDIwwCgYIKoZIzj0EAwIDSAAwRQIg\n" + - "AkIRVQBwrElFjrnqk5XPvnlnwkIm1A70ayqOf1FexoQCIQC8tBTn//RCfrhcgTjd\n" + - "ER4wRjFfFoc6lC68OHGVg9CZZg==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Tue Mar 02 02:53:40 PST 2021", System.out); - } -} - -class ComodoUserTrustRSA { - - // Owner: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Issuer: CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US - // Serial number: 284e39c14b386d889c7299e58cd05a57 - // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIGNDCCBBygAwIBAgIQKE45wUs4bYiccpnljNBaVzANBgkqhkiG9w0BAQwFADCB\n" + - "iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n" + - "cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n" + - "BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx\n" + - "MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBkTELMAkGA1UEBhMCR0IxGzAZBgNV\n" + - "BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE\n" + - "ChMPU2VjdGlnbyBMaW1pdGVkMTkwNwYDVQQDEzBTZWN0aWdvIFJTQSBFeHRlbmRl\n" + - "ZCBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUA\n" + - "A4IBDwAwggEKAoIBAQCaoslYBiqFev0Yc4TXPa0s9oliMcn9VaENfTUK4GVT7niB\n" + - "QXxC6Mt8kTtvyr5lU92hDQDh2WDPQsZ7oibh75t2kowT3z1S+Sy1GsUDM4NbdOde\n" + - "orcmzFm/b4bwD4G/G+pB4EX1HSfjN9eT0Hje+AGvCrd2MmnxJ+Yymv9BH9OB65jK\n" + - "rUO9Na4iHr48XWBDFvzsPCJ11Uioof6dRBVp+Lauj88Z7k2X8d606HeXn43h6acp\n" + - "LLURWyqXM0CrzedVWBzuXKuBEaqD6w/1VpLJvSU+wl3ScvXSLFp82DSRJVJONXWl\n" + - "dp9gjJioPGRByeZw11k3galbbF5gFK9xSnbDx29LAgMBAAGjggGNMIIBiTAfBgNV\n" + - "HSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQULGn/gMmHkK40\n" + - "4bTnTJOFmUDpp7IwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\n" + - "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDoGA1UdIAQzMDEwLwYEVR0g\n" + - "ADAnMCUGCCsGAQUFBwIBFhlodHRwczovL2Nwcy51c2VydHJ1c3QuY29tMFAGA1Ud\n" + - "HwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RS\n" + - "U0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYI\n" + - "KwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FB\n" + - "ZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0\n" + - "LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAQ4AzPxVypLyy3IjUUmVl7FaxrHsXQq2z\n" + - "Zt2gKnHQShuA+5xpRPNndjvhHk4D08PZXUe6Im7E5knqxtyl5aYdldb+HI/7f+zd\n" + - "W/1ub2N4Vq4ZYUjcZ1ECOFK7Z2zoNicDmU+Fe/TreXPuPsDicTG/tMcWEVM558OQ\n" + - "TJkB2LK3ZhGukWM/RTMRcRdXaXOX8Lh0ylzRO1O0ObXytvOFpkkkD92HGsfS06i7\n" + - "NLDPJEeZXqzHE5Tqj7VSAj+2luwfaXaPLD8lQEVci8xmsPGOn0mXE1ZzsChEPhVq\n" + - "FYQUsbiRJRhidKauhd+G2CkRTcR5fpsuz+iStB9s5Fks9lKoXnn0hv78VYjvR78C\n" + - "Cvj5FW/ounHjWTWMb3il9S5ngbFGcelB1l/MQkR63+1ybdi2OpjNWJCftxOWUpkC\n" + - "xaRdnOnSj7GQY0NLn8Gtq9FcSZydtkVgXpouSFZkXNS/MYwbcCCcRKBbrk8ss0SI\n" + - "Xg1gTURjh9VP1OHm0OktYcUw9e90wHIDn7h0qA+bWOsZquSRzT4s2crF3ZSA3tuV\n" + - "/UJ33mjdVO8wBD8aI5y10QreSPJvZHHNDyCmoyjXvNhR+u3arXUoHWxO+MZBeXbi\n" + - "iF7Nwn/IEmQvWBW8l6D26CXIavcY1kAJcfyzHkrPbLo+fAOa/KFl3lIU+0biEVNk\n" + - "Q9zXE6hC6X4=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, O=Sectigo Limited, STREET="3rd Floor, - // 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, ST=Manchester, OID.2.5.4.17=M5 3EQ, - // C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: 4e484426dbfed0c222b2ed152465614a - // Valid from: Mon Mar 01 16:00:00 PST 2021 until: Sat Apr 02 16:59:59 PDT 2022 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHTzCCBjegAwIBAgIQTkhEJtv+0MIisu0VJGVhSjANBgkqhkiG9w0BAQsFADCB\n" + - "kTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" + - "A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTkwNwYDVQQD\n" + - "EzBTZWN0aWdvIFJTQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIg\n" + - "Q0EwHhcNMjEwMzAyMDAwMDAwWhcNMjIwNDAyMjM1OTU5WjCCAToxETAPBgNVBAUT\n" + - "CDA0MDU4NjkwMRMwEQYLKwYBBAGCNzwCAQMTAkdCMR0wGwYDVQQPExRQcml2YXRl\n" + - "IE9yZ2FuaXphdGlvbjELMAkGA1UEBhMCR0IxDzANBgNVBBETBk01IDNFUTETMBEG\n" + - "A1UECBMKTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEWMBQGA1UECRMNVHJh\n" + - "ZmZvcmQgUm9hZDEWMBQGA1UECRMNRXhjaGFuZ2UgUXVheTElMCMGA1UECRMcM3Jk\n" + - "IEZsb29yLCAyNiBPZmZpY2UgVmlsbGFnZTEYMBYGA1UEChMPU2VjdGlnbyBMaW1p\n" + - "dGVkMTswOQYDVQQDEzJ1c2VydHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9yaXR5\n" + - "LWV2LmNvbW9kb2NhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" + - "AJ4f68XomMKS2uudXi7xp0fkRK4Q1pE2bamXB8PTsuyS9rhC8hD2zPr9Gs+NHAR0\n" + - "tG0GSWW1plzbpDFDEsCG+M+7fDl5cc/br8RLn75agZeKngv89y6RQUURxHq6N8hi\n" + - "lcJKHtWj9j6u1HYvu4u3lWWXQNbYnMWVqP1AVPZsGyDmKn/+Mc2ehvPdYSm/jQLr\n" + - "hH8Rudr12ZfKHTE4Xx7g5ZH0u52TEAWjuNCiXkhAYa/uUyEu3e7VlsnvxeqBENPn\n" + - "RwYhfT8mdXV6DvGrnv/NJj/tBTGE5kRbCh4HumY6I3x/XC5UeZE6rT+U6oeRgUOM\n" + - "6d7siAQVOspSqfTzR5HsBlECAwEAAaOCAvUwggLxMB8GA1UdIwQYMBaAFCxp/4DJ\n" + - "h5CuNOG050yThZlA6aeyMB0GA1UdDgQWBBR8+3Lw59S2HtjPs+KZcEJ+67fd/DAO\n" + - "BgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcD\n" + - "AQYIKwYBBQUHAwIwSQYDVR0gBEIwQDA1BgwrBgEEAbIxAQIBBQEwJTAjBggrBgEF\n" + - "BQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8w\n" + - "TTBLoEmgR4ZFaHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBRXh0ZW5k\n" + - "ZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGGBggrBgEFBQcBAQR6MHgw\n" + - "UQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1JTQUV4\n" + - "dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYX\n" + - "aHR0cDovL29jc3Auc2VjdGlnby5jb20wPQYDVR0RBDYwNIIydXNlcnRydXN0cnNh\n" + - "Y2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggEFBgorBgEE\n" + - "AdZ5AgQCBIH2BIHzAPEAdwBGpVXrdfqRIDC1oolp9PN9ESxBdL79SbiFq/L8cP5t\n" + - "RwAAAXfyrRCwAAAEAwBIMEYCIQCeOHfnABa6cl0EHTzyMj2t2qBqORBAC16hJIIl\n" + - "Y52W4QIhAKHDk1m9lW0kmcZJWEko3eA9QKJSDLNLpdUoBPzNNc76AHYAb1N2rDHw\n" + - "MRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMAAAF38q0R6wAABAMARzBFAiEAywsh\n" + - "8Ki6fFOExwR6de0qzTmf7bJMuQcY0Ry463/9R44CIDeAcX7Z9S1vlRB9gzVomNIN\n" + - "vkcnUazq7dowPnr5rYMOMA0GCSqGSIb3DQEBCwUAA4IBAQA3a+PBgH1SBVEDpgAN\n" + - "mWaqIQzJzMRfSgvopQ6nC8iD95SfYD/rvic7aOeBLh/5aEs/CknJsg6o0qB3wz1v\n" + - "T5JXd5JldRWw3nP80jkIaYgq97RUIkjcHhuw4hTyQP6wk7XVlPVLvBo9ePWxJjmn\n" + - "whxlSyxQ5A5NdrTqZOJmu9nFr2HXpX75kGwCkUKZI050FAZZydsK3LfMBTqe1Xwi\n" + - "PKyjXDWd40LjOEg31sA43ofO8n2pySP5LG5XAsvoAyPCy3zXhx5cdtmQFLIkntus\n" + - "DCfN+n51HPUo8r4PUhQtOiRUB3K871LTdwyv4/CRXS2fIhtO1pxYNKFOw0yrUf6j\n" + - "ECgk\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited, - // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, ST=Manchester, - // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: b07fd164b5790c9d5d1fddff5819cdb2 - // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIH5TCCBs2gAwIBAgIRALB/0WS1eQydXR/d/1gZzbIwDQYJKoZIhvcNAQELBQAw\n" + - "gZExCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" + - "BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UE\n" + - "AxMwU2VjdGlnbyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy\n" + - "IENBMB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFWMREwDwYDVQQF\n" + - "EwgwNDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0\n" + - "ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEzAR\n" + - "BgNVBAgTCk1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRy\n" + - "YWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNy\n" + - "ZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGDAWBgNVBAoTD1NlY3RpZ28gTGlt\n" + - "aXRlZDEaMBgGA1UECxMRQ09NT0RPIEVWIFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0\n" + - "cnVzdHJzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMIIB\n" + - "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnh/rxeiYwpLa651eLvGnR+RE\n" + - "rhDWkTZtqZcHw9Oy7JL2uELyEPbM+v0az40cBHS0bQZJZbWmXNukMUMSwIb4z7t8\n" + - "OXlxz9uvxEufvlqBl4qeC/z3LpFBRRHEero3yGKVwkoe1aP2Pq7Udi+7i7eVZZdA\n" + - "1ticxZWo/UBU9mwbIOYqf/4xzZ6G891hKb+NAuuEfxG52vXZl8odMThfHuDlkfS7\n" + - "nZMQBaO40KJeSEBhr+5TIS7d7tWWye/F6oEQ0+dHBiF9PyZ1dXoO8aue/80mP+0F\n" + - "MYTmRFsKHge6ZjojfH9cLlR5kTqtP5Tqh5GBQ4zp3uyIBBU6ylKp9PNHkewGUQID\n" + - "AQABo4IDbjCCA2owHwYDVR0jBBgwFoAULGn/gMmHkK404bTnTJOFmUDpp7IwHQYD\n" + - "VR0OBBYEFHz7cvDn1LYe2M+z4plwQn7rt938MA4GA1UdDwEB/wQEAwIFoDAMBgNV\n" + - "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNVHSAE\n" + - "QjBAMDUGDCsGAQQBsjEBAgEFATAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp\n" + - "Z28uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3Js\n" + - "LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FFeHRlbmRlZFZhbGlkYXRpb25TZWN1cmVT\n" + - "ZXJ2ZXJDQS5jcmwwgYYGCCsGAQUFBwEBBHoweDBRBggrBgEFBQcwAoZFaHR0cDov\n" + - "L2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2Vj\n" + - "dXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" + - "LmNvbTA9BgNVHREENjA0gjJ1c2VydHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9y\n" + - "aXR5LWV2LmNvbW9kb2NhLmNvbTCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA\n" + - "7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFtgzv54wAABAMARzBF\n" + - "AiB5PmhsK3zU3XdKvyxw/wWHMmLI7apHLa1yKdjkA8H+ggIhALdUx7Tl8aeWhK6z\n" + - "lh+PHvMAdCcAJK6w9qBJGQtSrYO5AHUAVYHUwhaQNgFK6gubVzxT8MDkOHhwJQgX\n" + - "L6OqHQcT0wwAAAFtgzv5zgAABAMARjBEAiBumSwAUamibqJXTN2cf/H3mjd0T35/\n" + - "UK9w2hu9gFobxgIgSXTLndHyqFUmcmquu3It0WC1yl6YMceGixbQL1e8BQcAdwC7\n" + - "2d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DO/nXAAAEAwBIMEYC\n" + - "IQDHRs10oYoXE5yq6WsiksjdQsUWZNpbSsrmz0u+KlxTVQIhAJ4rvHItKSeJLkaN\n" + - "S3YpVZnkN8tOwuxPsYeyVx/BtaNpMA0GCSqGSIb3DQEBCwUAA4IBAQAPFIsUFymo\n" + - "VTp0vntHrZpBApBQzDeriQv7Bi7tmou/Ng47RtXW3DjGdrePGSfOdl7h62k8qprU\n" + - "JeLyloDqhvmT/CG/hdwrfZ3Sv3N2xpetGcnW5S3oEi3m+/M1ls9eD+x1vybqV9Kd\n" + - "lcjuV7SYDlbvAS9w7TcygudhdW0cI8XTCvesGKohBkAlqaQ/MWYpt4WvsxHjbWgn\n" + - "5ZlIYR6A1ZFEjADifViH/5AA79lgGhAskkIWPjvRFalEVKTKtjhRK76eCfZs4Frr\n" + - "CEOpon+BeNKk+x/K/r10dSoWe0SV2uGVxTD83zkP++eREwo1hTgn8bXn7ftlnA3j\n" + - "7ml+Usz6udaD\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Tue Mar 02 02:55:42 PST 2021", System.out); - } -} - -class ComodoUserTrustECC { - - // Owner: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Issuer: CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US - // Serial number: 80f5606d3a162b143adc12fbe8c2066f - // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIDyTCCA0+gAwIBAgIRAID1YG06FisUOtwS++jCBm8wCgYIKoZIzj0EAwMwgYgx\n" + - "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" + - "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQD\n" + - "EyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEw\n" + - "MjAwMDAwMFoXDTMwMTIzMTIzNTk1OVowgZExCzAJBgNVBAYTAkdCMRswGQYDVQQI\n" + - "ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT\n" + - "D1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMwU2VjdGlnbyBFQ0MgRXh0ZW5kZWQg\n" + - "VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" + - "AQcDQgAEAyJ5Ca9JyXq8bO+krLVWysbtm7fdMSJ54uFD23t0x6JAC4IjxevfQJzW\n" + - "z4T6yY+FybTBqtOa++ijJFnkB5wKy6OCAY0wggGJMB8GA1UdIwQYMBaAFDrhCYbU\n" + - "zxnClnZ0SXbc4DXGY2OaMB0GA1UdDgQWBBTvwSqVDDLa+3Mw3IoT2BVL9xPo+DAO\n" + - "BgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggr\n" + - "BgEFBQcDAQYIKwYBBQUHAwIwOgYDVR0gBDMwMTAvBgRVHSAAMCcwJQYIKwYBBQUH\n" + - "AgEWGWh0dHBzOi8vY3BzLnVzZXJ0cnVzdC5jb20wUAYDVR0fBEkwRzBFoEOgQYY/\n" + - "aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0NlcnRpZmljYXRp\n" + - "b25BdXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0\n" + - "cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0FkZFRydXN0Q0EuY3J0\n" + - "MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMAoGCCqGSM49\n" + - "BAMDA2gAMGUCMQCjHztBDL90GCRXHlGqm0H7kzP04hd0MxwakKjWzOmstXNFLONj\n" + - "RFa0JqI/iKUJMFcCMCbLgyzcFW7DihtY5XE0XCLCw+git0NjxiFB6FaOFIlyDdqT\n" + - "j+Th+DJ92JLvICVD/g==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, O=Sectigo Limited, - // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, - // ST=Manchester, OID.2.5.4.17=M5 3EQ, - // C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: 9aa5da67480446fd7bf408fd5fdaa1d8 - // Valid from: Mon Mar 01 16:00:00 PST 2021 until: Sat Apr 02 16:59:59 PDT 2022 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFwTCCBWigAwIBAgIRAJql2mdIBEb9e/QI/V/aodgwCgYIKoZIzj0EAwIwgZEx\n" + - "CzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNV\n" + - "BAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMw\n" + - "U2VjdGlnbyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" + - "MB4XDTIxMDMwMjAwMDAwMFoXDTIyMDQwMjIzNTk1OVowggE6MREwDwYDVQQFEwgw\n" + - "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" + - "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEzARBgNV\n" + - "BAgTCk1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZm\n" + - "b3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBG\n" + - "bG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRl\n" + - "ZDE7MDkGA1UEAxMydXNlcnRydXN0ZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1l\n" + - "di5jb21vZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQtMl8R33Za\n" + - "WD6H8BW0+wybBf0+6+L5YYK/eyAVGm6vwjLaQZWlcdFBMKfaP1qTLi0VAabs4baS\n" + - "UkD8wR568pVpo4IC8zCCAu8wHwYDVR0jBBgwFoAU78EqlQwy2vtzMNyKE9gVS/cT\n" + - "6PgwHQYDVR0OBBYEFLOtYfOaIfDHZGubtKNELRR6A2srMA4GA1UdDwEB/wQEAwIH\n" + - "gDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJ\n" + - "BgNVHSAEQjBAMDUGDCsGAQQBsjEBAgEFATAlMCMGCCsGAQUFBwIBFhdodHRwczov\n" + - "L3NlY3RpZ28uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBHhkVodHRw\n" + - "Oi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29FQ0NFeHRlbmRlZFZhbGlkYXRpb25T\n" + - "ZWN1cmVTZXJ2ZXJDQS5jcmwwgYYGCCsGAQUFBwEBBHoweDBRBggrBgEFBQcwAoZF\n" + - "aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvRUNDRXh0ZW5kZWRWYWxpZGF0\n" + - "aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5z\n" + - "ZWN0aWdvLmNvbTA9BgNVHREENjA0gjJ1c2VydHJ1c3RlY2NjZXJ0aWZpY2F0aW9u\n" + - "YXV0aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCCAQMGCisGAQQB1nkCBAIEgfQEgfEA\n" + - "7wB2AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr8vxw/m1HAAABd/Kung0AAAQD\n" + - "AEcwRQIhAI16l52NctGAphhc6eh2kK2vO5QYk5nyouL3P6U/gG/dAiBfJRJ+iqE/\n" + - "noco35RpNtlV4GABrwmw1I/1R+L79VzwEAB1AG9Tdqwx8DEZ2JkApFEV/3cVHBHZ\n" + - "AsEAKQaNsgiaN9kTAAABd/KunvwAAAQDAEYwRAIgS+r3C10ua38DPJKvUJvW5bvL\n" + - "SCQ949n3sBJvhV6aXq4CIH/oEGgvJmKtMEjVKUQg8TrZO6LwQ+0sYfL79Qvm8wL3\n" + - "MAoGCCqGSM49BAMCA0cAMEQCID4Q9cc8OQ9tmKnnKZyplPsPipI5apVGkBqFRUSt\n" + - "zzM3AiAw5tw3cv/oabDsYdU+lmp5kZ/S3Z97ANAAaHE0AfXe/Q==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, - // O=Sectigo Limited, STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, - // L=Salford, OID.2.5.4.17=M5 3EQ, - // C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: 8b72489b7f505a55e2a22659c90ed2ab - // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGRTCCBeugAwIBAgIRAItySJt/UFpV4qImWckO0qswCgYIKoZIzj0EAwIwgZEx\n" + - "CzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNV\n" + - "BAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMw\n" + - "U2VjdGlnbyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" + - "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFBMREwDwYDVQQFEwgw\n" + - "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" + - "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" + - "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" + - "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" + - "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEaMBgGA1UECxMRQ09NT0RPIEVW\n" + - "IFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0cnVzdGVjY2NlcnRpZmljYXRpb25hdXRo\n" + - "b3JpdHktZXYuY29tb2RvY2EuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\n" + - "LTJfEd92Wlg+h/AVtPsMmwX9Puvi+WGCv3sgFRpur8Iy2kGVpXHRQTCn2j9aky4t\n" + - "FQGm7OG2klJA/MEeevKVaaOCA28wggNrMB8GA1UdIwQYMBaAFO/BKpUMMtr7czDc\n" + - "ihPYFUv3E+j4MB0GA1UdDgQWBBSzrWHzmiHwx2Rrm7SjRC0UegNrKzAOBgNVHQ8B\n" + - "Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" + - "BQUHAwIwSQYDVR0gBEIwQDA1BgwrBgEEAbIxAQIBBQEwJTAjBggrBgEFBQcCARYX\n" + - "aHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmg\n" + - "R4ZFaHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvRUNDRXh0ZW5kZWRWYWxp\n" + - "ZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGGBggrBgEFBQcBAQR6MHgwUQYIKwYB\n" + - "BQUHMAKGRWh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb0VDQ0V4dGVuZGVk\n" + - "VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYXaHR0cDov\n" + - "L29jc3Auc2VjdGlnby5jb20wPQYDVR0RBDYwNIIydXNlcnRydXN0ZWNjY2VydGlm\n" + - "aWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF/BgorBgEEAdZ5AgQC\n" + - "BIIBbwSCAWsBaQB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAAB\n" + - "bYL/SJoAAAQDAEcwRQIhAL7EJt/Rgz6NBnx2v8Hevux3Gpcxy64kaeyLVgFeNqFk\n" + - "AiBRf+OWLOtZzEav/oERljrk8hgZB4CR1nj/Tn98cmRrwwB2AFWB1MIWkDYBSuoL\n" + - "m1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYL/SIgAAAQDAEcwRQIgVtZZaiBMC2lu\n" + - "atBzUHQmOq4qrUQP7nS83cd3VzPhToECIQDnlpOCdaxJwr8C0MtkvYpKSabwBPFL\n" + - "ASEkwmOpjuQErAB3ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAAB\n" + - "bYL/SJoAAAQDAEgwRgIhAI8OgzP/kzF1bOJRHU2S/ewij/6HpGPy7Mbm7Hyuv3IU\n" + - "AiEAxDmX2FmORlgeerQmQ+ar3D9/TwA9RQckVDu5IrgweREwCgYIKoZIzj0EAwID\n" + - "SAAwRQIhAPwQWGWd3oR7YJ7ngCDQ9TAbdPgND51SiR34WfEgaTQtAiAxD4umKm02\n" + - "59GEMj5NpyF2ZQEq5mEGcjJNojrn+PC4zg==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Tue Mar 02 02:59:25 PST 2021", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,303 @@ +/* + * 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 8318759 + * @summary Interoperability tests with Digicert CS Root G5 certificates + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=ocsp,certpath DigicertCSRootG5 OCSP + * @run main/othervm -Djava.security.debug=certpath DigicertCSRootG5 CRL + */ + +public class DigicertCSRootG5 { + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + } + + new Digicert_CS_ECC().runTest(pathValidator); + new Digicert_CS_RSA().runTest(pathValidator); + } +} + +class Digicert_CS_ECC { + + // Owner: CN=DigiCert G5 CS ECC SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Issuer: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US + // Serial number: d926818addd3c47758f0ace9379b2e7 + // Valid from: Wed Feb 10 16:00:00 PST 2021 until: Sun Feb 10 15:59:59 PST 2036 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIDOTCCAsCgAwIBAgIQDZJoGK3dPEd1jwrOk3my5zAKBggqhkjOPQQDAzBNMQsw\n" + + "CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERp\n" + + "Z2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMjExMDAwMDAwWhcNMzYw\n" + + "MjEwMjM1OTU5WjBTMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu\n" + + "Yy4xKzApBgNVBAMTIkRpZ2lDZXJ0IEc1IENTIEVDQyBTSEEzODQgMjAyMSBDQTEw\n" + + "djAQBgcqhkjOPQIBBgUrgQQAIgNiAAS/zvKH4sLLu/zze3/+vHyfRE5OcO77TNw3\n" + + "MCMAlad2Y/ja50KTooGSmXhfwMXpbBTob7hsoxpvIU92W6DhFn9lg4pcKf5UHLEi\n" + + "0iDdHQ9w0hpFJiMABwK60nk+OwsGTZSjggFdMIIBWTASBgNVHRMBAf8ECDAGAQH/\n" + + "AgEAMB0GA1UdDgQWBBTXHcf6xvqCdCBFcTQSL1XVmEGSXjAfBgNVHSMEGDAWgBTw\n" + + "jJhxOThlwjobphdmHcjtZd6SNjAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYI\n" + + "KwYBBQUHAwMweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz\n" + + "cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj\n" + + "ZXJ0LmNvbS9EaWdpQ2VydENTRUNDUDM4NFJvb3RHNS5jcnQwRQYDVR0fBD4wPDA6\n" + + "oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0Q1NFQ0NQMzg0\n" + + "Um9vdEc1LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAKBggqhkjO\n" + + "PQQDAwNnADBkAjByCWijRCnJogZf94U5HG/5S4QFMxEOBSAyxECbFxgrXMKXh5qa\n" + + "7oS2F+hT2DPzxTwCMCIthK0X/14bxZvrNNiNSWzer2TDUyRw6HNIfnkHgqaGFQVA\n" + + "KyS5I77prv53stK0XQ==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN="Win The Customer, LLC", O="Win The Customer, LLC", L=Saratoga + // Springs, ST=Utah, C=US, SERIALNUMBER=9637546-0160, OID.2.5.4.15=Private + // Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Utah, OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=DigiCert G5 CS ECC SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: b13737c3caf58eecb4359f441522133 + // Valid from: Wed Jan 25 16:00:00 PST 2023 until: Tue Jan 28 15:59:59 PST 2025 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIEEjCCA5mgAwIBAgIQCxNzfDyvWO7LQ1n0QVIhMzAKBggqhkjOPQQDAzBTMQsw\n" + + "CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xKzApBgNVBAMTIkRp\n" + + "Z2lDZXJ0IEc1IENTIEVDQyBTSEEzODQgMjAyMSBDQTEwHhcNMjMwMTI2MDAwMDAw\n" + + "WhcNMjUwMTI4MjM1OTU5WjCB2TETMBEGCysGAQQBgjc8AgEDEwJVUzEVMBMGCysG\n" + + "AQQBgjc8AgECEwRVdGFoMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEV\n" + + "MBMGA1UEBRMMOTYzNzU0Ni0wMTYwMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRh\n" + + "aDEZMBcGA1UEBxMQU2FyYXRvZ2EgU3ByaW5nczEeMBwGA1UEChMVV2luIFRoZSBD\n" + + "dXN0b21lciwgTExDMR4wHAYDVQQDExVXaW4gVGhlIEN1c3RvbWVyLCBMTEMwWTAT\n" + + "BgcqhkjOPQIBBggqhkjOPQMBBwNCAASyShgaH44RcHazlEEMpwRKY4YebnygI9hG\n" + + "wTMQE/VFG40k3tR8lnyjgxTzZbC0aCVavdv1eglDGejQ+6iD8nzgo4IBxjCCAcIw\n" + + "HwYDVR0jBBgwFoAU1x3H+sb6gnQgRXE0Ei9V1ZhBkl4wHQYDVR0OBBYEFLGgEWb9\n" + + "GF89JoXyan/FD/auNIVVMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEF\n" + + "BQcDAzCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vY3JsMy5kaWdpY2VydC5j\n" + + "b20vRGlnaUNlcnRHNUNTRUNDU0hBMzg0MjAyMUNBMS5jcmwwP6A9oDuGOWh0dHA6\n" + + "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEc1Q1NFQ0NTSEEzODQyMDIxQ0Ex\n" + + "LmNybDA9BgNVHSAENjA0MDIGBWeBDAEDMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93\n" + + "d3cuZGlnaWNlcnQuY29tL0NQUzB+BggrBgEFBQcBAQRyMHAwJAYIKwYBBQUHMAGG\n" + + "GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBIBggrBgEFBQcwAoY8aHR0cDovL2Nh\n" + + "Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0RzVDU0VDQ1NIQTM4NDIwMjFDQTEu\n" + + "Y3J0MAwGA1UdEwEB/wQCMAAwCgYIKoZIzj0EAwMDZwAwZAIwLkWJc/eLxftorFCv\n" + + "ocOA1dfUFx7Al18d5Xsgpkx47kj2DWgQU+/bQEbbyPrKzYgCAjAP5ErLauJRC2to\n" + + "pPk/yXZYXsusmWVH7ozl9O5WR7+a3gVQ1zwVFWuqdjbq3zWWqJM=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Win the Customer LLC, O=Win the Customer LLC, L=Saratoga Springs, ST=Utah, C=US + // Issuer: CN=DigiCert G5 CS ECC SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: 201e51cb1ec8a56a1e8438c95adf024 + // Valid from: Sun Oct 22 17:00:00 PDT 2023 until: Tue Oct 22 16:59:59 PDT 2024 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIFdjCCBP2gAwIBAgIQAgHlHLHsilah6EOMla3wJDAKBggqhkjOPQQDAzBTMQsw\n" + + "CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xKzApBgNVBAMTIkRp\n" + + "Z2lDZXJ0IEc1IENTIEVDQyBTSEEzODQgMjAyMSBDQTEwHhcNMjMxMDIzMDAwMDAw\n" + + "WhcNMjQxMDIyMjM1OTU5WjB1MQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDEZ\n" + + "MBcGA1UEBxMQU2FyYXRvZ2EgU3ByaW5nczEdMBsGA1UEChMUV2luIHRoZSBDdXN0\n" + + "b21lciBMTEMxHTAbBgNVBAMTFFdpbiB0aGUgQ3VzdG9tZXIgTExDMIICIjANBgkq\n" + + "hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0o+FWNSfYzJmz+XgA7SRAIQd1H1pYnzq\n" + + "dPyNJJsd1G/nqfeHk/ezEx8Wd7iMJjcPOvKSd14uniAC3ayi3XOKKeFqEw5g5m2/\n" + + "JTO3n8xy9DK5CN1ctpK5Zy+UppOXrtTdBZB74/qSaREOysIfRLnVR4fxNy39urtl\n" + + "TJf0lvzRU9V6BQ3zRjMOCQnY6sueAPoQpVgpCVXkr4obJCkI5arkIQHVpfrcScaJ\n" + + "IzLQ46xL8nxoXPcGhikRystJKdbzg/oCFt68x87uSviZMtkqTHQhzRCzpO5pdx/z\n" + + "g64XZP8fAzSrM/uJCETXxMmazK6ZVkgPu3X4GvjfTfulvcJdxZNMm877NOSICtbL\n" + + "dKoBpvIeKtuyxrvmoJUfNw4e+LLbAQOFznVy7UxkTzG1INPgd57zu3Sm3ALq/oJZ\n" + + "oKfheM4zo8UevYMKmoki+N+qMHcJplPF8C04/u8CNc1Jk8tKmjgof8ZsGbQCC2+l\n" + + "NKXzTUnPpza4mHBMU3Qdd4iV8oxd/9jQyE71h11ISakWSresbCyC6HSOVUh409A1\n" + + "Mhv9+aEbqBNhAHJIYrQSY1hb98CKLRS6cABKAzr+HdafiPCAN3cdLGgJ5TWTIiBj\n" + + "AcjyHseVU4jeLIQl7/4gZATjePzSy/bo62SZXWzCOFp6zzy8VGGavRmMobe193gn\n" + + "cz/17hmFvqECAwEAAaOCAcQwggHAMB8GA1UdIwQYMBaAFNcdx/rG+oJ0IEVxNBIv\n" + + "VdWYQZJeMB0GA1UdDgQWBBR5Hkdl3jgG88ixGc1wEwO6N9Rn2TA+BgNVHSAENzA1\n" + + "MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNv\n" + + "bS9DUFMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIGNBgNV\n" + + "HR8EgYUwgYIwP6A9oDuGOWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy\n" + + "dEc1Q1NFQ0NTSEEzODQyMDIxQ0ExLmNybDA/oD2gO4Y5aHR0cDovL2NybDQuZGln\n" + + "aWNlcnQuY29tL0RpZ2lDZXJ0RzVDU0VDQ1NIQTM4NDIwMjFDQTEuY3JsMH4GCCsG\n" + + "AQUFBwEBBHIwcDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t\n" + + "MEgGCCsGAQUFBzAChjxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl\n" + + "cnRHNUNTRUNDU0hBMzg0MjAyMUNBMS5jcnQwCQYDVR0TBAIwADAKBggqhkjOPQQD\n" + + "AwNnADBkAjA9aX3CSzCOZiHdC6JBF0nQwPLGNipPdHFMSbINmfpuHCC3Go4prf8M\n" + + "WCsWEQr2gQYCMErfcrU8zfxnQ9SxsmGJ8jkM3MDGvAr0CtzDwmWis32V60jAUFBQ\n" + + "lGm/Mdb5/EqKpw==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Oct 23 14:48:38 PDT 2023", System.out); + } +} + +class Digicert_CS_RSA { + + // Owner: CN=DigiCert G5 CS RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Issuer: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US + // Serial number: 10262e16224ca6dfef584f8c63048db + // Valid from: Wed Feb 10 16:00:00 PST 2021 until: Sun Feb 10 15:59:59 PST 2036 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIGjDCCBHSgAwIBAgIQAQJi4WIkym3+9YT4xjBI2zANBgkqhkiG9w0BAQwFADBM\n" + + "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJDAiBgNVBAMT\n" + + "G0RpZ2lDZXJ0IENTIFJTQTQwOTYgUm9vdCBHNTAeFw0yMTAyMTEwMDAwMDBaFw0z\n" + + "NjAyMTAyMzU5NTlaMFcxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg\n" + + "SW5jLjEvMC0GA1UEAxMmRGlnaUNlcnQgRzUgQ1MgUlNBNDA5NiBTSEEzODQgMjAy\n" + + "MSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC1GOMV0tdTLLBk\n" + + "Ylmccgb6bFa9By5zkuLg9NfFMl4y9P9f21C7N+mMA4fWgfjEs+7/3ByGLaB+7/Pi\n" + + "TT3qXpvBz4uVWob9xv3lkAsIpwh/TMJulijy3GdpAQBMdvW/+HFrbRJGaJ3MM9d1\n" + + "pC3CRPmFWyXUpxqhb0FbMPA8OlsZNjg9fd/zCLevSJlL6ZdjfZ/4FiF26OfO60V6\n" + + "bOuTnd8JbDuwPfMWLP6qEinlFr7V9mjcZc4dfUWH70y7M6av7R1Tc68YQjrtPwIA\n" + + "5pdEcG/VeBVplpne1uxuc61ucVgTpjwOTV6E2KrCe+OCG8/m4voN7T4GC1RfPH3n\n" + + "PlCNV6MeiCVwExPhJFxZ+eTvhVJe0W7mriYpEo2kNR4pnSUhiS92vF4lI3ToAdnH\n" + + "LV+yx0VdsPVwEO344rsVNQvP/hrCHefKm3HsirlazTKpiI9OgZlkXohHanp8IgMx\n" + + "2HvBE/6HcCq/5PiRaeSzvFfRuotLS/LMCXaQEGV9JNSd1omKeNyaDqs89cNbf0g7\n" + + "Tn1AhAxb/TDIkIAV/1bU1UFeq48ufRCRpPO145JQXL7hfdUIth3AkvFRqLPbTsCH\n" + + "v/PcnKScv/QCtoYRnYv5LwdIvYblC+yqe7a9CVARsaVsGBw45wBevcMR5fcdriET\n" + + "ZjRNmQ5gMBjm/ZlHlzyBgShH6U22TQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgw\n" + + "BgEB/wIBADAdBgNVHQ4EFgQUiRgH/z5tMBfJNa27i3GG5Z9mksMwHwYDVR0jBBgw\n" + + "FoAUaAGTsdJKQEJplEYsHFqIqSW0R08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQM\n" + + "MAoGCCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDov\n" + + "L29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5k\n" + + "aWdpY2VydC5jb20vRGlnaUNlcnRDU1JTQTQwOTZSb290RzUuY3J0MEUGA1UdHwQ+\n" + + "MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydENTUlNB\n" + + "NDA5NlJvb3RHNS5jcmwwHAYDVR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJ\n" + + "KoZIhvcNAQEMBQADggIBALBxItkM8LmHhbsnkykSN6+HnLj9/hUx9UUcym1Hwoii\n" + + "Bl9VCCpibLDJurx1w19KL5S6j2ggOMn/1zBugWMVhn6j12RzD4HUkfLqNBXzQmRc\n" + + "xZoXxspSgqpk+jd5iMtVSDBzlaF7s1feDh9qKa7O/7OB5KAiIO2VYFx1ia9ne3tV\n" + + "lY98G+3TnEdjo7r9lBi4KDGmDJv56h7Sb4WeVFlJ/8b4u9IHblq3ykQ/LyKuCYDf\n" + + "v2bnqlT+HY4mgU9ZA0WoO/L7V7m0sBrBYhpdM0pmxlqn6mpvWIHA2tC4rsTY2TXn\n" + + "ZlXbyJaMd5mvjRjvK0DF/2yoKC+us/1li2blLZKS9k0Z36/m4D7z5nVXkmUvRvE2\n" + + "70BhJ0NnM5lHtytTR+OgiaPapeiDy6AA+VbdnV7hhINGEhP7tF3IZPPfmKZN7/bN\n" + + "Qr7wuKZx/jO5sTBtblBaOU2+xric+MlTt2k3ilDnO3EzkZOp1JMWnNjAZciRa8Gy\n" + + "bYAXrsxY4vQnxgA7dj1/3KDB+pCRT7CTMOJJQu27OOv0MuNkb1E+8chPx/eFwfrN\n" + + "rft1Eiqp3Te0w4njDkzukP6EMhebcTp3POm0YhMZl8s1fTI6DCcHFwcMVywXiWwv\n" + + "QG+Td+dHlFT0P8jq/ecaMj6s8j69q36MER+QMyrxGAl3MHyEA7BBut1WCh9dsOnY\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN="Win The Customer, LLC", O="Win The Customer, LLC", L=Saratoga + // Springs, ST=Utah, C=US + // Issuer: CN=DigiCert G5 CS RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: bfec2fd49eeacb347ddbea5c1576083 + // Valid from: Fri Jun 23 17:00:00 PDT 2023 until: Wed Jun 26 16:59:59 PDT 2024 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGqzCCBJOgAwIBAgIQC/7C/UnurLNH3b6lwVdggzANBgkqhkiG9w0BAQsFADBX" + + "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xLzAtBgNVBAMT" + + "JkRpZ2lDZXJ0IEc1IENTIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIzMDYy" + + "NDAwMDAwMFoXDTI0MDYyNjIzNTk1OVowdzELMAkGA1UEBhMCVVMxDTALBgNVBAgT" + + "BFV0YWgxGTAXBgNVBAcTEFNhcmF0b2dhIFNwcmluZ3MxHjAcBgNVBAoTFVdpbiBU" + + "aGUgQ3VzdG9tZXIsIExMQzEeMBwGA1UEAxMVV2luIFRoZSBDdXN0b21lciwgTExD" + + "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsElsbtoNNIL5fCadUzW+" + + "aDl2LF0c6BRckZSuH1f88tFD5LDjuT+rdIxsjDS/dqedRiilJe40z/3973OZNaxs" + + "wxYCSHhUV9XimSHH0zQ2MpbupdA7aLDYM4tcypam1Zm9q6njLArBUgGVaKYBUZqW" + + "obVh+6aFBzj36u7EmPgLCJsre5oheo8+gOwfu+xVExceoHG+V7XTKhD6vhclS49B" + + "UIHgvpn+/BlB8kjf5M2XzmpfWg9aGq75gnd1ix4fU1BnA0A33cZPrFsi5cMh6NZd" + + "tI4WIpb5P8X17G3yRqNMM/noBvBrtpQHVLpN2C2NLg0YX1FjIK7bcBKFOnIG36ou" + + "vs+QesMyVOXeKKnt1ERBSqwrMjUuqN7W6YnXjoIp7xWxEdIdae+1fDK702zhGaYv" + + "b6pYGoJ7HQI/x7S6kF462qvXsf++yA5kxr2qNTSNY4ZggzEwubvu0PYRYjMHwIUn" + + "SV3ZlRAKXK2AO7GydecWr2QVRra4+myCznsil/rKasWTAgMBAAGjggHRMIIBzTAf" + + "BgNVHSMEGDAWgBSJGAf/Pm0wF8k1rbuLcYbln2aSwzAdBgNVHQ4EFgQUfr+syABm" + + "R7FB/f155oky+e5fLR8wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF" + + "BwMDMIGVBgNVHR8EgY0wgYowQ6BBoD+GPWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv" + + "bS9EaWdpQ2VydEc1Q1NSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwQ6BBoD+GPWh0" + + "dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEc1Q1NSU0E0MDk2U0hBMzg0" + + "MjAyMUNBMS5jcmwwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYb" + + "aHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGCBggrBgEFBQcBAQR2MHQwJAYI" + + "KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBMBggrBgEFBQcwAoZA" + + "aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0RzVDU1JTQTQwOTZT" + + "SEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQCj" + + "HCYM2aGyHFpdWRkbxa+so37uyPDJ27wpn4oNhaSKKletB8Xr6rMa5JBJ1NUa2S9Q" + + "3CYvdH9pGjjThUJPR0Lg8DrZNkPtqyjQLQ86tYfjteoKe5SXTxZ0epXikRTXySFa" + + "NM1KOEf5CJq7OywLLXVxm+F2VEX2+PzLAtHxViGeN7AsZMbWGlp3VkymVITcKkP3" + + "vnsoF6Teacb019xxBDCLuhNG91rlzhG0YrJ3qMlPyStmzxqy+2UIlPwFeLRkBkRG" + + "K7Kxi2xvYbgdFP93kRbwJbp8d3x/JG3LpwAZv+NV0TY3jBj7ymGoGuiSV0nU9XPt" + + "yDm1FYYZAH2ykwo8YPZqAcu+EHvyxi1dgOM3ABfoLJfOIYJv2gxPx+KIKzn1wzBS" + + "kk1HMf8xbYXs40vF2Lrb7AQIyLa2ZskJTyfb0dyEyOq+vvVgLA9ZdwidzD1RnVf6" + + "vOb7KbMSBCLK+HGqHrW+hhSDi2vHvSit7Cn+q80ZmzRqvJ/+mVl+ppnjDC7nSLIa" + + "qeG0fvUz6SabPX7yV92D5ARrJJ3xgAvgmgWfuKBV7WlEGCmj0QTWZ0/AFBLzNcq7" + + "+0rgP0GM98MZpKa8pHZaS1A3uP1TFzamfVGdv0FVHXSkN5Kvg0iPh4Qz9TRiCkyE" + + "boJeU1LYdyTrP/+q3zQqsGa9xdQ50EovjWymbvWzCQ==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Win the Customer LLC, O=Win the Customer LLC, L=Saratoga Springs, + // ST=Utah, C=US + // Issuer: CN=DigiCert G5 CS RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: f409d101094769abaf06f085f11ca4f + // Valid from: Sun Oct 22 17:00:00 PDT 2023 until: Tue Oct 22 16:59:59 PDT 2024 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIHKTCCBRGgAwIBAgIQD0CdEBCUdpq68G8IXxHKTzANBgkqhkiG9w0BAQsFADBX\n" + + "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xLzAtBgNVBAMT\n" + + "JkRpZ2lDZXJ0IEc1IENTIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIzMTAy\n" + + "MzAwMDAwMFoXDTI0MTAyMjIzNTk1OVowdTELMAkGA1UEBhMCVVMxDTALBgNVBAgT\n" + + "BFV0YWgxGTAXBgNVBAcTEFNhcmF0b2dhIFNwcmluZ3MxHTAbBgNVBAoTFFdpbiB0\n" + + "aGUgQ3VzdG9tZXIgTExDMR0wGwYDVQQDExRXaW4gdGhlIEN1c3RvbWVyIExMQzCC\n" + + "AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANKPhVjUn2MyZs/l4AO0kQCE\n" + + "HdR9aWJ86nT8jSSbHdRv56n3h5P3sxMfFne4jCY3DzrykndeLp4gAt2sot1ziinh\n" + + "ahMOYOZtvyUzt5/McvQyuQjdXLaSuWcvlKaTl67U3QWQe+P6kmkRDsrCH0S51UeH\n" + + "8Tct/bq7ZUyX9Jb80VPVegUN80YzDgkJ2OrLngD6EKVYKQlV5K+KGyQpCOWq5CEB\n" + + "1aX63EnGiSMy0OOsS/J8aFz3BoYpEcrLSSnW84P6AhbevMfO7kr4mTLZKkx0Ic0Q\n" + + "s6TuaXcf84OuF2T/HwM0qzP7iQhE18TJmsyumVZID7t1+Br43037pb3CXcWTTJvO\n" + + "+zTkiArWy3SqAabyHirbssa75qCVHzcOHviy2wEDhc51cu1MZE8xtSDT4Hee87t0\n" + + "ptwC6v6CWaCn4XjOM6PFHr2DCpqJIvjfqjB3CaZTxfAtOP7vAjXNSZPLSpo4KH/G\n" + + "bBm0AgtvpTSl801Jz6c2uJhwTFN0HXeIlfKMXf/Y0MhO9YddSEmpFkq3rGwsguh0\n" + + "jlVIeNPQNTIb/fmhG6gTYQBySGK0EmNYW/fAii0UunAASgM6/h3Wn4jwgDd3HSxo\n" + + "CeU1kyIgYwHI8h7HlVOI3iyEJe/+IGQE43j80sv26OtkmV1swjhaes88vFRhmr0Z\n" + + "jKG3tfd4J3M/9e4Zhb6hAgMBAAGjggHRMIIBzTAfBgNVHSMEGDAWgBSJGAf/Pm0w\n" + + "F8k1rbuLcYbln2aSwzAdBgNVHQ4EFgQUeR5HZd44BvPIsRnNcBMDujfUZ9kwPgYD\n" + + "VR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdp\n" + + "Y2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD\n" + + "AzCBlQYDVR0fBIGNMIGKMEOgQaA/hj1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20v\n" + + "RGlnaUNlcnRHNUNTUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMEOgQaA/hj1odHRw\n" + + "Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHNUNTUlNBNDA5NlNIQTM4NDIw\n" + + "MjFDQTEuY3JsMIGCBggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v\n" + + "Y3NwLmRpZ2ljZXJ0LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGln\n" + + "aWNlcnQuY29tL0RpZ2lDZXJ0RzVDU1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJ\n" + + "BgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQAKCH6ri6f507/j2ifF7VQbavWE\n" + + "Wn4T63PzJveL6/kedV7avhrQ/B6uHrez1xy/RH/MlL/B+TF6YTg+ILqtKR/PyJrg\n" + + "N+1RON0Eg3AEWWDtGl3KBYFlklz8Szo+xmXf5GYiqueejbxscH1BA0PU/5CgGkr6\n" + + "1Kk4OXqKqmpuPeQCxca1ARDD749E/2IFsDGC8kBCWepV62l0/xcDKWD5Zn+y4Tkh\n" + + "5+YJJ21D746sNDOsDNJ4DuqEYrXWUH6BlT5EDYelGqRCOdyTYUdDg+QcSFWnH7wR\n" + + "O+eIA3BLSw0x1Vh6DJRKm5H644sPVppaI1jVZDe+zBwp2e/j8XH7KDlp/WaRUhcU\n" + + "bjGg2Ss5TMbBjR6B4nMwjvqaCIFoAD6aFRYc80px/KY6KTSyOFF0FBQNuhSsUZQy\n" + + "p74aRjUraSu/RiJMA8A6OYGo1b7W9o/UOg0MB4WQkfwl+Mxh+58QKjLjZr9VVapW\n" + + "4yv0G/G6rT/pHrRiyBcT7Kt4xNFsmMFAN4BXL9WI9mkGDa4iwDmWVjIjAaiilaaC\n" + + "MIXwwm3eg/QBgWBUrwXf3YC+1HXkaFDZc5apQ5uaNJPjQo9nQ6xqfpnACXTJ/Lwm\n" + + "JBu4YlXPby5Vh6mWWSyVdbICrCD7BtGP8aSBPFGPEuPEjK32uyeoGWVwwSubVFPX\n" + + "ARhLX5oSFZUySvHgYg==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Oct 23 14:44:23 PDT 2023", System.out); + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,179 @@ +/* + * 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 8319187 + * @summary Interoperability tests with eMudhra emSign Root CA G2 CS root + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=certpath EmSignRootG2CA OCSP + * @run main/othervm -Djava.security.debug=certpath EmSignRootG2CA CRL + */ + +public class EmSignRootG2CA { + + // Owner: CN=emSign CS CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN + // Issuer: CN=emSign Root CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN + // Serial number: c084e666596139a1fa9b + // Valid from: Sun Feb 18 10:30:00 PST 2018 until: Fri Feb 18 10:30:00 PST 2033 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIGeDCCBGCgAwIBAgILAMCE5mZZYTmh+pswDQYJKoZIhvcNAQEMBQAwZzELMAkG\n" + + "A1UEBhMCSU4xEzARBgNVBAsTCmVtU2lnbiBQS0kxJTAjBgNVBAoTHGVNdWRocmEg\n" + + "VGVjaG5vbG9naWVzIExpbWl0ZWQxHDAaBgNVBAMTE2VtU2lnbiBSb290IENBIC0g\n" + + "RzIwHhcNMTgwMjE4MTgzMDAwWhcNMzMwMjE4MTgzMDAwWjBlMQswCQYDVQQGEwJJ\n" + + "TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s\n" + + "b2dpZXMgTGltaXRlZDEaMBgGA1UEAxMRZW1TaWduIENTIENBIC0gRzIwggIiMA0G\n" + + "CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDYYkv6Q9an5RylOJ6rkTAHT0cAwfYg\n" + + "ZsFKk/Hz/4VwWYsmzf+Z7M8i3CK3mnUcqgw0AIzrVLUwxiKAaL0qca+SbXwOk/7p\n" + + "Y/zwwLdg0OhHVGeeU3OTvkbsBpiLS08i7ids9FGrte6m1kqk+QSOY2F5AESxA4+F\n" + + "AKXGtzIImQd15m67C88AzzFsvszAAxSvVTqs4hb8BcRnUCzlAp7gMJSwwrrgTiEv\n" + + "6Ap6cFVT+n1oj6370sd5KBiRelLoqZtQx4njoNJkJlM30ftPNMGnqPLCloQ6koP/\n" + + "dAdpmwWB+F0/5d5UVmVPC3R/F8w7aX3fdSC8+M2E/ZXPVIYkEquLT7K2yXhRl3hn\n" + + "xwG6qqGp6TjvKvhiyac8qieu9YNG1R+PVFqejOFMohV2g0Z5MfwaruhUCNwHHeZs\n" + + "Dv/MVYMiHcV+5qU+MMzcKngb3RCmq0jzCb+MESomEMiAieCC15W7YC/LpgDHO0jY\n" + + "vV4AdLquUHfsOnhT2KD7mEg2PnL7JOwoQSFtuJYmM/coh+Y6CIoV3x+aV1bO7FDF\n" + + "ap33u36lE639oQj0tTqW3n1WcyNxhD0lwGlYIAjG8XnhRjtl6/MVVrGuyPWpB4TH\n" + + "u8CgNT0roENuq13RnHbBz2rLnndenHiMbxCyElGJBpZfXiF1H25KHUzvyzxt++L+\n" + + "hSfprX9BSXLpGQIDAQABo4IBJTCCASEwHwYDVR0jBBgwFoAU7exNRWEYKOezIygR\n" + + "HE2lJw1e7PQwHQYDVR0OBBYEFBWGyrZ0lhdIWDSCLM3S4XWer0S3MA4GA1UdDwEB\n" + + "/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDAzA9BgNVHSAENjA0MDIGBFUdIAAw\n" + + "KjAoBggrBgEFBQcCARYcaHR0cDovL3JlcG9zaXRvcnkuZW1zaWduLmNvbTASBgNV\n" + + "HRMBAf8ECDAGAQH/AgEAMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0\n" + + "cDovL29jc3AuZW1zaWduLmNvbTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js\n" + + "LmVtc2lnbi5jb20/Um9vdENBRzIuY3JsMA0GCSqGSIb3DQEBDAUAA4ICAQCDkogs\n" + + "d5Tv1zwsQdk15btzYK/oI1tEwvN6IpIM9rSqIrje8XnXKjHHmbHX6emHIR31bxuK\n" + + "7mY77XjrJMWp+71udC/DgDy4tfZTXIzEekI0XQfcui1UPC08Ysl0taQKTANwsAOV\n" + + "VSi7boSGqLet0qSmeKVyQ5/blbwx1NhjyLTyi66rVYf7fYdPV55X5TKUJdKDgiRI\n" + + "BomNVRcrrnHZtS8+t9CXxSXR35VAu2ube44Tl+dQHIWz9XwLxtYFwIPSEdqPpoAu\n" + + "5XEVo7evwMHQoY/MQj6Ywbw6tYh6bHu6C/qrp4oSyYXbz2ZWlHkz1oEXvefi7a9Z\n" + + "6mKnnaY3UYHq5AI+k6ojazVFbSTenb/TO/Z247gdhG7Wssshd6pgyqcTEa+FZz+F\n" + + "5ZZdoiIl8UJsTCPPg0xP9Ab0WE3BjCCqTPt+Czbd3cgBxiBS7KTQs/DnQRFuPCjC\n" + + "khbDtHsCN4aUoLM9OOw94/ZcoU0G5cg9mSvONBxUv9W7SIpJreXXMPXixcBKULoJ\n" + + "focui3s0yzGqTA9tSzQ4nmA9aXBCAAxrABlY/hk10ImeBa1SPjocRb/vuCaGp74T\n" + + "n8oADP42XudDnp8wlOKWxFJulhNi960Rev+5vZOPF/LGfS78GI6yzBjR49VJGhOP\n" + + "EJK8NSNmK3FNblQfOyFM7VE0uOGHOUwpMGVM2A==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=test, OU=test, O=test, L=test, ST=test, C=IN + // Issuer: CN=emSign CS CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN + // Serial number: 7c9ade672c0ad1b6 + // Valid from: Wed Aug 30 05:39:25 PDT 2023 until: Sat Aug 30 05:39:25 PDT 2025 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGNjCCBB6gAwIBAgIIfJreZywK0bYwDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UE\n" + + "BhMCSU4xEzARBgNVBAsTCmVtU2lnbiBQS0kxJTAjBgNVBAoTHGVNdWRocmEgVGVj\n" + + "aG5vbG9naWVzIExpbWl0ZWQxGjAYBgNVBAMTEWVtU2lnbiBDUyBDQSAtIEcyMB4X\n" + + "DTIzMDgzMDEyMzkyNVoXDTI1MDgzMDEyMzkyNVowWDELMAkGA1UEBhMCSU4xDTAL\n" + + "BgNVBAgTBHRlc3QxDTALBgNVBAcTBHRlc3QxDTALBgNVBAoMBHRlc3QxDTALBgNV\n" + + "BAsTBHRlc3QxDTALBgNVBAMTBHRlc3QwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw\n" + + "ggGKAoIBgQC04pOiSFbl7Bd4wFYXzzyukKh+EmwIq8xRGQDkuYH+C6Zao36VAV+k\n" + + "xGw7lmM3rf4YUcArgZYHfrxgPJNBbGrCi/YnEPYQTNwSrBAePUx1tt13LVBxHfNu\n" + + "cQQT+kqE7064WsYfmfr/uzJZemqVH7lG82DN23+8E/235AIh3lz/pn7T9ByLj7TV\n" + + "zWP40oT0UfQXQvWUpFevPONu/RksRP+NiKV3ji6/wYpvrfodzkrGxw2DPfOh4Iam\n" + + "j6bBH2rkTMToH853plsQGr2ji8OndePfvDdk+5c33Jz1knCNPZSlYQIIp8scyz4z\n" + + "jaUGdoC140FjEA1SMA2WzpRJoE7xjAidLv7jiV596/bTwrIM+IZhzBc8SKRmkdZ6\n" + + "lYjPYJHPqRosRtfxcQne3pY6F4s1aOUtuGJaQS/AJkkykZoOx27plWM5SjtmlrL+\n" + + "7g2/ihWT9CEagYuo44tqk9Tmp3P37+ADAmiXxP0zUxYIv77DSabdArrZ+AB5XUol\n" + + "V8sxE1V6h0UCAwEAAaOCAXUwggFxMB8GA1UdIwQYMBaAFBWGyrZ0lhdIWDSCLM3S\n" + + "4XWer0S3MB0GA1UdDgQWBBQ2k0TE2p46sYwI5M/a1XJ8M5Oc8DAOBgNVHQ8BAf8E\n" + + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwNwYDVR0fBDAwLjAsoCqgKIYmaHR0\n" + + "cDovL2NybC5lbXNpZ24uY29tP2VtU2lnbkNTQ0FHMi5jcmwwTgYDVR0gBEcwRTA5\n" + + "BgsrBgEEAYOOIQEAATAqMCgGCCsGAQUFBwIBFhxodHRwOi8vcmVwb3NpdG9yeS5l\n" + + "bVNpZ24uY29tMAgGBmeBDAEEATBzBggrBgEFBQcBAQRnMGUwIgYIKwYBBQUHMAGG\n" + + "Fmh0dHA6Ly9vY3NwLmVtU2lnbi5jb20wPwYIKwYBBQUHMAKGM2h0dHA6Ly9yZXBv\n" + + "c2l0b3J5LmVtc2lnbi5jb20vY2VydHMvZW1TaWduQ1NDQUcyLmNydDAMBgNVHRMB\n" + + "Af8EAjAAMA0GCSqGSIb3DQEBDAUAA4ICAQBKLa7j8fNpcnWNv7NegrMKTRy7gycI\n" + + "qrMK848wISX6jl2wg6b275sWQHzQRxA6rbB76bF2HXLFcpITJPaz+vjetYOVQd4v\n" + + "l8iZN52OpN6Pwrheiz7JhdLiHisN+2NKMmF899bH7w1l2Sr/FQl5vqk41gwwWMen\n" + + "99Waf4Bp6p3lvBArK2BbabTs8+16xvmkHEK3d3l3Bu6qTEbQRgUI5XsVXmXXn8Pg\n" + + "IANliTEsbsN9CMWrJ56ciEujU7w2L+IBfvKhl10N1AQNHwpQzwfFyz2BUbACN75o\n" + + "feIUBarM3ssNzpnt7idgkCTwWVrdEL1NHyW967aEMWyVwaRrtkjFOW/0xuSr2rEI\n" + + "jBpPj5RPdP6ZEaqnmg5PIgSrJ8FBjx6JmvVgZH/XEl5MZ7PsvJFfIMun6RxXtGn7\n" + + "QP0+ipkRrI6USNFS84H53Q0WJhQWZUgd3cdm37wpFGvxOVEskIgJNW9SbOgiT9sB\n" + + "zTIy3ceOK2onmUkDM2Q2+Hbc7A4BmNIlW4fpYXvZlM7IXSl9U3Voks92Hi45azgz\n" + + "StWZv9+Ronmmp+b7JKCe7MZXIBHfj0JhAVNJiYTZ9BqkY2VRvuQPVUdKxske9fQ6\n" + + "ciFJ5a6RDOhce6pFloaQu39ci2XCY1N4mIR3vFzpmBNkttlEXviK07XNTv9cnQt6\n" + + "3CW5aMAsfTbmOw==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=test, OU=test, O=test, L=test, ST=test, C=IN + // Issuer: CN=emSign CS CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN + // Serial number: cf02dedd03d2f509 + // Valid from: Thu Oct 05 22:38:51 PDT 2023 until: Sun Oct 05 22:38:51 PDT 2025 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIGNzCCBB+gAwIBAgIJAM8C3t0D0vUJMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNV\n" + + "BAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRl\n" + + "Y2hub2xvZ2llcyBMaW1pdGVkMRowGAYDVQQDExFlbVNpZ24gQ1MgQ0EgLSBHMjAe\n" + + "Fw0yMzEwMDYwNTM4NTFaFw0yNTEwMDYwNTM4NTFaMFgxCzAJBgNVBAYTAklOMQ0w\n" + + "CwYDVQQIEwR0ZXN0MQ0wCwYDVQQHEwR0ZXN0MQ0wCwYDVQQKDAR0ZXN0MQ0wCwYD\n" + + "VQQLEwR0ZXN0MQ0wCwYDVQQDEwR0ZXN0MIIBojANBgkqhkiG9w0BAQEFAAOCAY8A\n" + + "MIIBigKCAYEAmUSghjvjUvVgYguH2PMLwW4TwtYsNDpAuGPqux53lI9v9S5u4oAv\n" + + "m1Sa3MW7CeEnhHNAIFu/AKvNXSfkvnJpTozWstZMjd93DcNacteBG0fBKTkIq+5k\n" + + "A8qIBiXWk8NORlbjV5bXnoW2pO7wbrALDK3FGf2JAQjuYWXE1mlVk0+SJewUSN+F\n" + + "XTl63V3tcaqjxhoViY8/dCWc7pNTPgQ/f+Rmnm1bpE0hxVPpQ29+60lyoNtKiOWj\n" + + "InKRKBV8jYkR/xI13bKWguaxZnswpf2MrophQTvO9ivPHADWhZlNYYjYYEMl4tbi\n" + + "rG2EquJ7g8Jdo+aL3BggLv5gFkpfoEcaveNuUWy7ggUl7MNhvgDdWdoi6VY7R8Fi\n" + + "F52+JqPByGpHkZKi0wPa3BaI7guGGyCn3TMe66kNTMS4ADxHktqQlpNSaYYl/84G\n" + + "lnr2WxQt/W+sXoorlKc/Kh0ubbm6eDzPE8kkIDV2uIxUEgSL7SJQ95yf5XgRihoH\n" + + "KoBA45iR5vCtAgMBAAGjggF1MIIBcTAfBgNVHSMEGDAWgBQVhsq2dJYXSFg0gizN\n" + + "0uF1nq9EtzAdBgNVHQ4EFgQUDs5dk74eElzdEKdxIlkzISoWSFkwDgYDVR0PAQH/\n" + + "BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDcGA1UdHwQwMC4wLKAqoCiGJmh0\n" + + "dHA6Ly9jcmwuZW1zaWduLmNvbT9lbVNpZ25DU0NBRzIuY3JsME4GA1UdIARHMEUw\n" + + "OQYLKwYBBAGDjiEBAAEwKjAoBggrBgEFBQcCARYcaHR0cDovL3JlcG9zaXRvcnku\n" + + "ZW1TaWduLmNvbTAIBgZngQwBBAEwcwYIKwYBBQUHAQEEZzBlMCIGCCsGAQUFBzAB\n" + + "hhZodHRwOi8vb2NzcC5lbVNpZ24uY29tMD8GCCsGAQUFBzAChjNodHRwOi8vcmVw\n" + + "b3NpdG9yeS5lbXNpZ24uY29tL2NlcnRzL2VtU2lnbkNTQ0FHMi5jcnQwDAYDVR0T\n" + + "AQH/BAIwADANBgkqhkiG9w0BAQwFAAOCAgEAGa2XSoRkoIkHHHGXrdzTBCf/+KgK\n" + + "FlHhqlBOk5rwLDX1sfNlmsaz10I69phE90Ac8Coa/xCrBaFrTYqRvmkY9gU19jkn\n" + + "FdVcwQEHNku7Ro/Z/mbyi+aTBzHMTy0Vl4HqVnQInjV891n64SerUuAB7wNVOOho\n" + + "GoBfpf6lzDzzuEmetFokHYv1tWGQqPF/dHLARQraUlQpWjsnOx0QcZ5cM79REONE\n" + + "y6uzXT2vaatT3ns8Mtx8zooq+t8pnZlXJqlrwNTcnPad9gSsVu6vfsnWhLhz0VLG\n" + + "sYPXcWIssLbBQW3v5z0l1Isj7vy2UFfbn8AmZ0PanPo3v3C2sk19DK+Zlc9xBAXc\n" + + "KKwc4m8le6QkP/EB2wUA7ey5Cf29hjNDJpZznquEaWl9aKbBRdJDKsK88IBJjzK0\n" + + "Gbpw9fYJ3txuGA7Q27gyaZAeGAIrFvOtRY0XFbr20qSh2GBBYN57+lBPh4UKqgy8\n" + + "Z2Kk/2jK9k+nm41JYCmwVZHg3Va9RRfW8FkeE95gAUFPDWjeV+GvcimCbcB3DwaZ\n" + + "9fy1qfV4xsduhC3ei6f7Ask8LbAEWaEIXmgK10YbIfhzomCyCzlA+E+gwkq/bmkv\n" + + "B8hh27KWA6IRt7URI51MZlh0e8fULyXlOZcoJA/IPX9RdePa2RHFuPSypBHjoN7z\n" + + "6bCML1XZ2xnHIAg=\n" + + "-----END CERTIFICATE-----"; + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + } + + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Thu Oct 05 22:51:36 PDT 2023", System.out); + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EntrustCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EntrustCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EntrustCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EntrustCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8195774 8243321 - * @summary Interoperability tests with Entrust CAs - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath EntrustCA OCSP - * @run main/othervm -Djava.security.debug=certpath EntrustCA CRL - */ - -/* - * Obtain test artifacts for Entrust CA from: - * - * EC CA: - * Valid: https://validec.entrust.net - * Revoked https://revokedec.entrust.net - * - * G4 CA: - * Valid: https://validg4.entrust.net - * Revoked: https://revokedg4.entrust.net - */ -public class EntrustCA { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - boolean ocspEnabled = false; - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - ocspEnabled = true; - } - - new Entrust_ECCA().runTest(pathValidator, ocspEnabled); - new Entrust_G4().runTest(pathValidator, ocspEnabled); - } -} - -class Entrust_ECCA { - - // Owner: CN=Entrust Certification Authority - L1J, OU="(c) 2016 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - // Issuer: CN=Entrust Root Certification Authority - EC1, OU="(c) 2012 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIID5zCCA2ygAwIBAgIQCoPUgD5+n1EAAAAAUdTB9zAKBggqhkjOPQQDAzCBvzEL\n" + - "MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1Nl\n" + - "ZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEy\n" + - "IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UE\n" + - "AxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4X\n" + - "DTE2MDQwNTIwMTk1NFoXDTM3MTAwNTIwNDk1NFowgboxCzAJBgNVBAYTAlVTMRYw\n" + - "FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu\n" + - "bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNiBFbnRydXN0LCBJbmMu\n" + - "IC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxLjAsBgNVBAMTJUVudHJ1c3QgQ2Vy\n" + - "dGlmaWNhdGlvbiBBdXRob3JpdHkgLSBMMUowdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n" + - "AAT14eFXmpQX/dEf7NAxrMH13n0btz1KKvH2S1rROGPAKex2CY8yxznbffK/MbCk\n" + - "F7ByYXGs1+8kL5xmTysU/c+YmjOZx2mMSAk2DPw30fijJ3tRrwChZ+TBpgtB6+A5\n" + - "MsCjggEuMIIBKjAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAz\n" + - "BggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmVudHJ1c3Qu\n" + - "bmV0MDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZW50cnVzdC5uZXQvZWMx\n" + - "cm9vdC5jcmwwOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHA6\n" + - "Ly93d3cuZW50cnVzdC5uZXQvcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF\n" + - "BQcDAjAdBgNVHQ4EFgQUw/lFA77I+Qs8RTXz63Ls5+jrlJswHwYDVR0jBBgwFoAU\n" + - "t2PnGt2N6QimVYOk4GpQQWURQkkwCgYIKoZIzj0EAwMDaQAwZgIxAPnVAOqxKDd7\n" + - "v37EBmpPqWCCWBFPKW6HpRx3GUWc9caeQIw8rO2HXYgf92pb/TsJYAIxAJhI0MpR\n" + - "z5L42xF1R9UIPfQxCMwgsnWBqIqcfMrMO+2DxQy6GIP3cFFj9gRyxguKWw==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=validec.entrust.net, SERIALNUMBER=D15576572, OID.2.5.4.15=Private Organization, O="Entrust, Inc.", - // OID.1.3.6.1.4.1.311.60.2.1.2=Maryland, OID.1.3.6.1.4.1.311.60.2.1.3=US, L=Kanata, ST=Ontario, C=CA - // Issuer: CN=Entrust Certification Authority - L1J, OU="(c) 2016 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFrTCCBTKgAwIBAgIQYtgW4DLwh74AAAAAVqBXkTAKBggqhkjOPQQDAjCBujEL\n" + - "MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1Nl\n" + - "ZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDE2\n" + - "IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEuMCwGA1UE\n" + - "AxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEwxSjAeFw0xODA2\n" + - "MjUxMzE1NTdaFw0xOTA2MjUxMzQ1NTBaMIHJMQswCQYDVQQGEwJDQTEQMA4GA1UE\n" + - "CBMHT250YXJpbzEPMA0GA1UEBxMGS2FuYXRhMRMwEQYLKwYBBAGCNzwCAQMTAlVT\n" + - "MRkwFwYLKwYBBAGCNzwCAQITCE1hcnlsYW5kMRYwFAYDVQQKEw1FbnRydXN0LCBJ\n" + - "bmMuMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjESMBAGA1UEBRMJRDE1\n" + - "NTc2NTcyMRwwGgYDVQQDExN2YWxpZGVjLmVudHJ1c3QubmV0MFkwEwYHKoZIzj0C\n" + - "AQYIKoZIzj0DAQcDQgAEHQe7lUaAUgIwR9EiLJlhkbx+HfSr22M3JvQD6+fnYgqd\n" + - "55e6E1UE45fk92UpqPi1CEbXrdpmWKu1Z470B9cPGaOCAwcwggMDMB4GA1UdEQQX\n" + - "MBWCE3ZhbGlkZWMuZW50cnVzdC5uZXQwggF/BgorBgEEAdZ5AgQCBIIBbwSCAWsB\n" + - "aQB1AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABZDcxpMkAAAQD\n" + - "AEYwRAIgIb0PwjCcNOchJg8Zywz/0Lwm2vEOJUSao6BqNUIsyaYCIElHHexB06LE\n" + - "yXWDXO7UqOtWT6uqkdJN8V4TzwT9B4o4AHcA3esdK3oNT6Ygi4GtgWhwfi6OnQHV\n" + - "XIiNPRHEzbbsvswAAAFkNzGkvgAABAMASDBGAiEAlxy/kxB9waIifYn+EV550pvA\n" + - "C3jUfS/bjsKbcsBH9cQCIQDSHTJORz6fZu8uLFhpV525pw7iHVh2dSn3gpcteObh\n" + - "DQB3ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABZDcxpTsAAAQD\n" + - "AEgwRgIhAPCBqVqSvAEIXMPloV0tfBEEdjRrAhiG407cPqYwt9AFAiEAuQf4R5os\n" + - "MLkD3XhxvrTDvnD+PUOf8PzPevsWkuxNqcQwDgYDVR0PAQH/BAQDAgeAMB0GA1Ud\n" + - "JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBjBggrBgEFBQcBAQRXMFUwIwYIKwYB\n" + - "BQUHMAGGF2h0dHA6Ly9vY3NwLmVudHJ1c3QubmV0MC4GCCsGAQUFBzAChiJodHRw\n" + - "Oi8vYWlhLmVudHJ1c3QubmV0L2wxai1lYzEuY2VyMDMGA1UdHwQsMCowKKAmoCSG\n" + - "Imh0dHA6Ly9jcmwuZW50cnVzdC5uZXQvbGV2ZWwxai5jcmwwSgYDVR0gBEMwQTA2\n" + - "BgpghkgBhvpsCgECMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5u\n" + - "ZXQvcnBhMAcGBWeBDAEBMB8GA1UdIwQYMBaAFMP5RQO+yPkLPEU18+ty7Ofo65Sb\n" + - "MB0GA1UdDgQWBBT+J7OhS6gskCanmOGnx10DPSF8ATAJBgNVHRMEAjAAMAoGCCqG\n" + - "SM49BAMCA2kAMGYCMQCQLUQABT74TmdHzAtB97uNF5+Zy15wzkmlKeRSOXCIf2C5\n" + - "YKjsgdkR1OdzZXcpjNgCMQDfWcdPhodNXZC4l1lLPOPaTzPPw6uVqqoITQlc6r1t\n" + - "dRkkD6K9ii/X8EtwoFp7s80=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revokedec.entrust.net, SERIALNUMBER=115868500, OID.2.5.4.15=Private Organization, O="Entrust, Inc.", - // OID.1.3.6.1.4.1.311.60.2.1.2=Texas, OID.1.3.6.1.4.1.311.60.2.1.3=US, L=Kanata, ST=Ontario, C=CA - // Issuer: CN=Entrust Certification Authority - L1J, OU="(c) 2016 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGJzCCBaygAwIBAgIRAM0WDfag1taIAAAAAFagJ5gwCgYIKoZIzj0EAwIwgbox\n" + - "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9T\n" + - "ZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAx\n" + - "NiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxLjAsBgNV\n" + - "BAMTJUVudHJ1c3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBMMUowHhcNMTcw\n" + - "NTI0MTcwNzA4WhcNMTkwNTI0MTczNjU1WjCByDELMAkGA1UEBhMCQ0ExEDAOBgNV\n" + - "BAgTB09udGFyaW8xDzANBgNVBAcTBkthbmF0YTETMBEGCysGAQQBgjc8AgEDEwJV\n" + - "UzEWMBQGCysGAQQBgjc8AgECEwVUZXhhczEWMBQGA1UEChMNRW50cnVzdCwgSW5j\n" + - "LjEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xEjAQBgNVBAUTCTExNTg2\n" + - "ODUwMDEeMBwGA1UEAxMVcmV2b2tlZGVjLmVudHJ1c3QubmV0MFkwEwYHKoZIzj0C\n" + - "AQYIKoZIzj0DAQcDQgAEN5MP/59yrs9uwVM/Mrc8IuHonMChAZgN2twwvh8KTnR2\n" + - "3stfem/R+NtLccq+4ds1+8ktnXgP7u1x0as6IJOH1qOCA4EwggN9MCAGA1UdEQQZ\n" + - "MBeCFXJldm9rZWRlYy5lbnRydXN0Lm5ldDCCAfcGCisGAQQB1nkCBAIEggHnBIIB\n" + - "4wHhAHYA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFcO4iiogAA\n" + - "BAMARzBFAiAgHVpryyNVgnsUIihu+5DC2/vuP8Cy5iXq8NhCBXg8UgIhAKi5jImT\n" + - "f1FJksvHboc0EZh9TWhWljVZ6E5jB2CL+qzeAHcAVhQGmi/XwuzT9eG9RLI+x0Z2\n" + - "ubyZEVzA75SYVdaJ0N0AAAFcO4ij9QAABAMASDBGAiEA4B2p2726ISSkKC9WVlzj\n" + - "BVwYZ1Hr7mTjPrFqkoGpEHYCIQC5iuInkJXGBANLTH06BHIQkkr4KnFRl9QBOSw4\n" + - "b+kNqgB1AN3rHSt6DU+mIIuBrYFocH4ujp0B1VyIjT0RxM227L7MAAABXDuIpkcA\n" + - "AAQDAEYwRAIgQ9ssw19wIhHWW6IWgwnIyB7e30HacBNX6S1eQ3GUX04CICffGj3A\n" + - "WWmK9lixmk35YklMnSXNqHQezSYRiCYtXxejAHcApLkJkLQYWBSHuxOizGdwCjw1\n" + - "mAT5G9+443fNDsgN3BAAAAFcO4inUwAABAMASDBGAiEA+8T9tpPw/mU/STsNv0oz\n" + - "8Nla21fKlpEOyWqDKWPSUeYCIQCwI5tDyyaJtyFY9/OVqLG+BKPKjscUtTqGJYl4\n" + - "XbOo1jAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF\n" + - "BwMCMGMGCCsGAQUFBwEBBFcwVTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50\n" + - "cnVzdC5uZXQwLgYIKwYBBQUHMAKGImh0dHA6Ly9haWEuZW50cnVzdC5uZXQvbDFq\n" + - "LWVjMS5jZXIwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5l\n" + - "dC9sZXZlbDFqLmNybDBKBgNVHSAEQzBBMDYGCmCGSAGG+mwKAQIwKDAmBggrBgEF\n" + - "BQcCARYaaHR0cDovL3d3dy5lbnRydXN0Lm5ldC9ycGEwBwYFZ4EMAQEwHwYDVR0j\n" + - "BBgwFoAUw/lFA77I+Qs8RTXz63Ls5+jrlJswHQYDVR0OBBYEFIj28ytR8ulo1p2t\n" + - "ZnBQOLK0rlLUMAkGA1UdEwQCMAAwCgYIKoZIzj0EAwIDaQAwZgIxANzqGRI0en5P\n" + - "gSUDcdwoQSNKrBPBfGz2AQVLHAXsxvIlGhKZAQtM49zxA8AdFy/agwIxAMEjJH6A\n" + - "4UbcGZc40eYu6wUbAxiUDD3gwSElNQ8Z6IhNLPCCdMM6KZORyaagAcXn4A==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Wed May 24 10:39:28 PDT 2017", System.out); - } -} - -class Entrust_G4 { - - // Owner: CN=Entrust Certification Authority - L1N, OU="(c) 2014 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - // Issuer: CN=Entrust Root Certification Authority - G4, OU="(c) 2015 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIGMjCCBBqgAwIBAgIRAKvsd/8bQQwHAAAAAFVl2AUwDQYJKoZIhvcNAQELBQAw\n" + - "gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL\n" + - "Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg\n" + - "MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw\n" + - "BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0\n" + - "MB4XDTE3MTEyMjIwMDQyMFoXDTMwMTIyMjIwMzQyMFowgboxCzAJBgNVBAYTAlVT\n" + - "MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1\n" + - "c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNCBFbnRydXN0LCBJ\n" + - "bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxLjAsBgNVBAMTJUVudHJ1c3Qg\n" + - "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBMMU4wggEiMA0GCSqGSIb3DQEBAQUA\n" + - "A4IBDwAwggEKAoIBAQDcSG+caYQ4xcvf+dt8bgCEHorO0g5j0H1NOtQzRXgUoG8y\n" + - "QuRbJX9swyKqQZbsc18YvTV8OKA/uSNE46Jvq47TFPojWWTVLbNDqpM07e4EFYKs\n" + - "A9NFzAUngijnf3ivnXA6iNPAMXaEhXmhY/YFjk8NoM7Y1PFsA0oj5hamKQ06iO/j\n" + - "gvBScLmnQ1ju9Qj9IGIg18UL5AJNw0frspLUQBYVrLGaqAy5Nl2BUJKaZ4vnSLvP\n" + - "nk6YrB15mo1phHae10Ba4fx7R3z8IZ/hby4OXTy/KZpu107VEQPAwTuDK8ZXxB5y\n" + - "0DSzi4vaw27aLrUsq4aFqUo03gEfC31vWW76TNkFAgMBAAGjggErMIIBJzAOBgNV\n" + - "HQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEF\n" + - "BQcDAQYIKwYBBQUHAwIwOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEW\n" + - "Gmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBhMDMGCCsGAQUFBwEBBCcwJTAjBggr\n" + - "BgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMAYDVR0fBCkwJzAloCOg\n" + - "IYYfaHR0cDovL2NybC5lbnRydXN0Lm5ldC9nNGNhLmNybDAdBgNVHQ4EFgQU7kfR\n" + - "hXHx/S23P7s+Y1h3F0lADpUwHwYDVR0jBBgwFoAUnzjEViPDOeigcWzoVEzk6Dqx\n" + - "v2cwDQYJKoZIhvcNAQELBQADggIBACMeFFgsWmC7h6D1v8DJUkOpm/m5UhVhO0hb\n" + - "pQMQKMhKkl744Y9SWG4WNmpQy743TTciEJPZFhc7ke2R6VmK8ZJUqro2awOw1RWZ\n" + - "OtHla59Btf1NQd41vOVdU+qFhs8lFfXg9sK7YHTrfxHtMXLoGnkkamK3xJgn7sXa\n" + - "/zUvUDBTpDCXcpO9SyHoKIQswmkIPpRyIdPF4biRdR3N+9MYmlfqN/Nk3OEZ73xZ\n" + - "AUZP6Gu+f9cEiHTA8NdYHCPLJWyFnIHWK+QuTFEnKYnOYxCeroLBNOO64e8JWZ39\n" + - "kZ22BBXhHzqOCCczS7JOJTRF+JgvWuxbFwRstj8qf3fE+JndWmq2FC4hTHtpuK5K\n" + - "ENuiRm5gdkXfsXmB+qB6y5gaajiTIMscGIcZIKTe2YdKrLoicvEz8k+loM7favik\n" + - "vzFioTNTDHYGx3mkfElBE7ycY8n+jZE3QBBv33k28MeQi7XNgEaMc4tYwoZIdE9A\n" + - "xVccXTzEQzka82dOkRB1dU0XZId9XAWv+CtNc2TjF6Wgx2seA/c6H8S0IfgQBIV2\n" + - "8iN2wZns2QFdawkdy3hMUqPnA++kuGhLW3GemsIY5dP/WxY8rd+OfLb/Ks9T1pCd\n" + - "28t7PQRcQsgkYmouzrOW9ASBvYqLLdhl4y+fFXff8RkPIKMNoYP06WJvRKmky9R/\n" + - "41/nXRas\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=validg4.entrust.net, SERIALNUMBER=1913605, OID.2.5.4.15=Private Organization, - // O=Entrust Datacard Limited, OID.1.3.6.1.4.1.311.60.2.1.2=Ontario, OID.1.3.6.1.4.1.311.60.2.1.3=CA, - // L=Ottawa, ST=Ontario, C=CA - // Issuer: CN=Entrust Certification Authority - L1N, OU="(c) 2014 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - // Serial number: 83790beb78eeb966007ad3dbf11d570 - // Valid from: Fri May 29 13:29:00 PDT 2020 until: Sun Aug 28 13:34:23 PDT 2022 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFpjCCBI6gAwIBAgIQCDeQvreO65ZgB609vxHVcDANBgkqhkiG9w0BAQsFADCB\n" + - "ujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsT\n" + - "H1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAy\n" + - "MDE0IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEuMCwG\n" + - "A1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEwxTjAeFw0y\n" + - "MDA1MjkyMDI5MDBaFw0yMjA4MjgyMDM0MjNaMIHRMQswCQYDVQQGEwJDQTEQMA4G\n" + - "A1UECBMHT250YXJpbzEPMA0GA1UEBxMGT3R0YXdhMRMwEQYLKwYBBAGCNzwCAQMT\n" + - "AkNBMRgwFgYLKwYBBAGCNzwCAQITB09udGFyaW8xITAfBgNVBAoTGEVudHJ1c3Qg\n" + - "RGF0YWNhcmQgTGltaXRlZDEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + - "EDAOBgNVBAUTBzE5MTM2MDUxHDAaBgNVBAMTE3ZhbGlkZzQuZW50cnVzdC5uZXQw\n" + - "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC508f77Kp/kfbqs9DHfa+V\n" + - "977gsVzI78TzfN4tF3ujwnPgd9mzLArM71VJvceOJUto7ywRasxmFxOLHf7WN2Kg\n" + - "U1yk/Kp9WUNfjmjIkI+JfCTkaz1RztpW85GNN9SL/W2yFIxv0ijAiGoQeC7J80Ni\n" + - "+y31Q5+M0oPMzngBOtD8LpyVt+/lSwUvxwhlChu7LWpIFmBUriILkvh11vxaItZV\n" + - "Jm4g8amE33/eXPFjZxB4ABQpBMC4QVg10UP+DpimZuJa6oQZfoNUjDF2yKlyrA+z\n" + - "s3kK8SXzJhE5LQxBp158jAoCVZuER08cumw3wvXI5NGzkzDxpTGacDO0bDo2ULpN\n" + - "AgMBAAGjggGNMIIBiTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUH\n" + - "AwIGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOA38RC6Sv6hMUgY\n" + - "eLACjvqO13vsMB8GA1UdIwQYMBaAFO5H0YVx8f0ttz+7PmNYdxdJQA6VMGgGCCsG\n" + - "AQUFBwEBBFwwWjAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQw\n" + - "MwYIKwYBBQUHMAKGJ2h0dHA6Ly9haWEuZW50cnVzdC5uZXQvbDFuLWNoYWluMjU2\n" + - "LmNlcjAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1c3QubmV0L2xl\n" + - "dmVsMW4uY3JsMB4GA1UdEQQXMBWCE3ZhbGlkZzQuZW50cnVzdC5uZXQwSwYDVR0g\n" + - "BEQwQjA3BgpghkgBhvpsCgECMCkwJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LmVu\n" + - "dHJ1c3QubmV0L3JwYTAHBgVngQwBATANBgkqhkiG9w0BAQsFAAOCAQEAOExxxxEk\n" + - "iAZZ4RJSWwI/CBQYAlUmd2wb/SBk9eYNAu/UL0XiAbwbOjH2dV6JHwAdwn0eoPR1\n" + - "KK/E1/OVoVibVBdxLMISPqdodRgHps6kGCOJxS8Zz8d3AEvx27EQ/Hg/EwIJZsUK\n" + - "dyb48V6a3XzExqLiwGu9oI9Ozm3/mo11ixmhvSFXH+FZf93qvvCSO+XTGGrLv5ja\n" + - "Tkazn/HgnwUBHd1TiO0jLhAdc+rZyd/SDjXMAXsa99zVfc2MY0Mb8+MohNHOwqYg\n" + - "tuYuirvtt9P0oteauL+iEBCRcqsmJaHGeaEyJH2QMxC5W22KpW245eHisW7rMoGQ\n" + - "9nbGmfe97p7bHQ==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revokedg4.entrust.net, SERIALNUMBER=1913605, OID.2.5.4.15=Private Organization, - // O=Entrust Datacard Limited, OID.1.3.6.1.4.1.311.60.2.1.2=Ontario, OID.1.3.6.1.4.1.311.60.2.1.3=CA, - // L=Ottawa, ST=Ontario, C=CA - // Issuer: CN=Entrust Certification Authority - L1N, OU="(c) 2014 Entrust, Inc. - for authorized use only", - // OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US - // Serial number: 24c5f46412b9dcc242a93017176979d6 - // Valid from: Fri May 29 13:36:00 PDT 2020 until: Sun Aug 28 13:40:43 PDT 2022 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIFqjCCBJKgAwIBAgIQJMX0ZBK53MJCqTAXF2l51jANBgkqhkiG9w0BAQsFADCB\n" + - "ujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsT\n" + - "H1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAy\n" + - "MDE0IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEuMCwG\n" + - "A1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEwxTjAeFw0y\n" + - "MDA1MjkyMDM2MDBaFw0yMjA4MjgyMDQwNDNaMIHTMQswCQYDVQQGEwJDQTEQMA4G\n" + - "A1UECBMHT250YXJpbzEPMA0GA1UEBxMGT3R0YXdhMRMwEQYLKwYBBAGCNzwCAQMT\n" + - "AkNBMRgwFgYLKwYBBAGCNzwCAQITB09udGFyaW8xITAfBgNVBAoTGEVudHJ1c3Qg\n" + - "RGF0YWNhcmQgTGltaXRlZDEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + - "EDAOBgNVBAUTBzE5MTM2MDUxHjAcBgNVBAMTFXJldm9rZWRnNC5lbnRydXN0Lm5l\n" + - "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN6Bvaj7EG752e15UQH9\n" + - "4o8+660Gi3caUAAu45vZebO7EfRgrz0zyalpiexmQzocGn6Zog2yVqmMZjrMY11a\n" + - "q96s0pzVKImnA/787G7J5lRncP+PM6/WGtUUGS2hHiifoW5Ya/kcI1uk6EDT0leb\n" + - "HIedOiwcfDkq38g5ckuWNae24DAD8AM9XBJXMuNbuiqo03wMlDL3Jif8wNQfpmPD\n" + - "b+KR6IwGJdYwLBMoMcPmZF0rykW3YTO2NTDGCwvT8zzvjIKp8caRkI6pfkKmc89U\n" + - "Nvgbk/d9JEsgQLbYmRKVnhtnt756U7v3+0kZITxzfsBvQZ6zC7X4FAcTN1302RGn\n" + - "NGsCAwEAAaOCAY8wggGLMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF\n" + - "BQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQULjRc9DEsa0kD\n" + - "uhKNo6cCqQ+mPjgwHwYDVR0jBBgwFoAU7kfRhXHx/S23P7s+Y1h3F0lADpUwaAYI\n" + - "KwYBBQUHAQEEXDBaMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l\n" + - "dDAzBggrBgEFBQcwAoYnaHR0cDovL2FpYS5lbnRydXN0Lm5ldC9sMW4tY2hhaW4y\n" + - "NTYuY2VyMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZW50cnVzdC5uZXQv\n" + - "bGV2ZWwxbi5jcmwwIAYDVR0RBBkwF4IVcmV2b2tlZGc0LmVudHJ1c3QubmV0MEsG\n" + - "A1UdIAREMEIwNwYKYIZIAYb6bAoBAjApMCcGCCsGAQUFBwIBFhtodHRwczovL3d3\n" + - "dy5lbnRydXN0Lm5ldC9ycGEwBwYFZ4EMAQEwDQYJKoZIhvcNAQELBQADggEBAGab\n" + - "wtgpooQW3YL2Cqk9RDJFbNct5BSbzgY9qN1TOe4L7gbjV0BJBCcsHOCjvbgEuzME\n" + - "FC/kAmBu7eMnKVAqCCsWaI8XV7xB7P/BqHpvf9LI/GyHg4wCYdxgFGBXHOjlSy+8\n" + - "YWRM5UnFUknqbj1B4u2/U+U3X66QXi+MWrmBdjpcMahpY5zP1Bh90OmIc8DY4arf\n" + - "widObgJe2H/VFScudLf5JMpBso2v772GYTRr5Tqqq3ouS9WvDf0NBvoStt1oiUMP\n" + - "oowesfNiaYa/rZzWRlhYNs089KUeLhjOZswtIY5LCyy+Wt3CHgXljGEQFgi7p59s\n" + - "gk0aMRYM9Gri26VbD5A=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Fri May 29 13:42:13 PDT 2020", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GlobalSignR6CA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GlobalSignR6CA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GlobalSignR6CA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GlobalSignR6CA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - /* - * @test - * @bug 8216577 8249176 - * @summary Interoperability tests with GlobalSign R6 CA - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath GlobalSignR6CA OCSP - * @run main/othervm -Djava.security.debug=certpath GlobalSignR6CA CRL - */ - - /* - * - * Obtain TLS test artifacts for GlobalSign R6 CA from: - * - * Valid TLS Certificates: - * https://valid.r6.roots.globalsign.com/ - * - * Revoked TLS Certificates: - * https://revoked.r6.roots.globalsign.com/ - */ -public class GlobalSignR6CA { - - // Owner: CN=GlobalSign Atlas R6 EV TLS CA 2020, O=GlobalSign nv-sa, C=BE - // Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6 - // Serial number: 7803182afbecd89eb19309bb4a25bdaa - // Valid from: Mon Jul 27 17:00:00 PDT 2020 until: Sat Jul 27 17:00:00 PDT 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIGwDCCBKigAwIBAgIQeAMYKvvs2J6xkwm7SiW9qjANBgkqhkiG9w0BAQwFADBM\n" + - "MSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xv\n" + - "YmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0yMDA3MjgwMDAwMDBaFw0z\n" + - "MDA3MjgwMDAwMDBaMFUxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWdu\n" + - "IG52LXNhMSswKQYDVQQDEyJHbG9iYWxTaWduIEF0bGFzIFI2IEVWIFRMUyBDQSAy\n" + - "MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtQ8IiN2Ukq/Clynv\n" + - "HhqugFQg5SXIyVO4ZRnxo0hNnaek78LRn4Bkaqcwv6Ls0Ftn4bK2zvBaS1zsfUTA\n" + - "vfup/s86zHCRvOqAL8zO/WiMV1G5ikHSlD6RtpIOHRX4y0oIGW59ADY0ANwDeDWL\n" + - "x/RgSltuQIqeGXwZnyZFwWtxVkSE4p5tn2Lb6USzwcD22taiXmeYsPMWfJfmWPRj\n" + - "ZuYBgxn6tvUVRO+ZzAUKEEaJK/LVLieAVEmfR6anEJ/gWczxz12Lwu6qF5ov0OQt\n" + - "AP0rfruyje/EJt6xHjpJ2OgDzCWYstXOpRPDHYS3klpaRbowAlpJdYMRAqY5CNiP\n" + - "RAx3wvsWCVI5UkzKVD6RuHHVpfzfdKAfsjHa/aSunHtTpE+NUf3Q/3qHXW5cyDnP\n" + - "Jt6VTVVVevjTquwH1xrUigukDbeopV1owsqIA5aw2io7RbBorwPBA0veinHN4vP9\n" + - "X8jbTiIiLjlfJOnHZe7pIhb3T9WCqhwwsBNPQpKizGHCj5kL2UJe7N5u4RywFOZE\n" + - "l5mbTX4zO6Vj3WM9ZVbZgXVNwEjS5mYq/rvC1yr9obNUJ8br6JAd2ZBnzhA5Zn4s\n" + - "bIP99TlUBZWczw+vPM7g1S4e4cyd+8CULVhVs87QlyvwWnRbH7fXZo8xLzhzMCjB\n" + - "8Y0cNdL1S6QKrrhC6Pf6tV/JU20CAwEAAaOCAZMwggGPMA4GA1UdDwEB/wQEAwIB\n" + - "hjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB\n" + - "/wIBADAdBgNVHQ4EFgQUhNwhC8eoXXKXhId+8tW2+nFWTvswHwYDVR0jBBgwFoAU\n" + - "rmwFo5MT4qLn4tcc1sfwf8hnU6AwewYIKwYBBQUHAQEEbzBtMC4GCCsGAQUFBzAB\n" + - "hiJodHRwOi8vb2NzcDIuZ2xvYmFsc2lnbi5jb20vcm9vdHI2MDsGCCsGAQUFBzAC\n" + - "hi9odHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9yb290LXI2LmNy\n" + - "dDA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL3Jv\n" + - "b3QtcjYuY3JsMFUGA1UdIAROMEwwQQYJKwYBBAGgMgEBMDQwMgYIKwYBBQUHAgEW\n" + - "Jmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMAcGBWeBDAEB\n" + - "MA0GCSqGSIb3DQEBDAUAA4ICAQBD+97H2N1BgiliKQFrb+jcWjkmPP8cdF/eiBW1\n" + - "cEzOOhsuVqxbyIk8qdw3UueHSDjqWUjHYoo8TV3DLqUXmIy1Ks3MkESsFKeLpEbk\n" + - "VMZga0lbDnqqRc5a2yzrXmwVYDeWVeD20s5vPoKCnFzmcR+2v9TKD4bI6XWVl84q\n" + - "GzfFRVdY9f8KN+7891+47ZhptvxtNqJKVI2O+EAP/PvTpwes983LkFzsev4/+Qxs\n" + - "EszD7/pE+Byj3t9CMat2XoX0jfJjbEXgewFb/gCwHvqNKLNWrYfE9qN8b6qm4xQk\n" + - "qGQKTrFKsBJx4TU+h10qXDhpmOBswiJqoG16XCV32oSn0JUYvXVAvP6YjueOv/jr\n" + - "0ZMTWGh8wCz6v3XBaXR0rxDAz9GImpU+xPx2XjuHac7OnYbN+i8p7cJPUxABjHiA\n" + - "LWXIZtCn5ziCfvYC6+SCp8x9TPJzAIfJ4NKv/8SpvvzuchVkAQqlQaGFBEdkX84R\n" + - "I/WYYG+2BliFIpbQnfljYWCURbfsYz7+Zxb94+4yzva49p8T6lALoK3s2kqIVLKN\n" + - "s6qAnk/qX6JihkaR3W+iViHMC5tqQX/pd8QIXccF3PA2OdeNGU4iUNZqUbYB4VZd\n" + - "AaOaeaUl0LwAta6DB5w344eUIqDgaitSwQZBnxppmwL3tGzP1ero2e2RvBmphbxI\n" + - "atIdxA==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=valid.r6.roots.globalsign.com, - // O=GMO GlobalSign LTD, STREET="Springfield House, Sandling Road", OID.2.5.4.17=ME14 2LP, L=Maidstone, ST=Kent, - // C=GB, SERIALNUMBER=04705639, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB - // Issuer: CN=GlobalSign Atlas R6 EV TLS CA 2020, O=GlobalSign nv-sa, C=BE - // Serial number: 1aff2829dd8bf07aa65a7b3c920ca4b - // Valid from: Thu Aug 27 00:20:06 PDT 2020 until: Tue Sep 28 00:20:06 PDT 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHyjCCBbKgAwIBAgIQAa/ygp3YvweqZaezySDKSzANBgkqhkiG9w0BAQsFADBV\n" + - "MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTErMCkGA1UE\n" + - "AxMiR2xvYmFsU2lnbiBBdGxhcyBSNiBFViBUTFMgQ0EgMjAyMDAeFw0yMDA4Mjcw\n" + - "NzIwMDZaFw0yMTA5MjgwNzIwMDZaMIH6MRMwEQYLKwYBBAGCNzwCAQMTAkdCMR0w\n" + - "GwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjERMA8GA1UEBRMIMDQ3MDU2Mzkx\n" + - "CzAJBgNVBAYTAkdCMQ0wCwYDVQQIDARLZW50MRIwEAYDVQQHDAlNYWlkc3RvbmUx\n" + - "ETAPBgNVBBEMCE1FMTQgMkxQMSkwJwYDVQQJDCBTcHJpbmdmaWVsZCBIb3VzZSwg\n" + - "U2FuZGxpbmcgUm9hZDEbMBkGA1UECgwSR01PIEdsb2JhbFNpZ24gTFREMSYwJAYD\n" + - "VQQDDB12YWxpZC5yNi5yb290cy5nbG9iYWxzaWduLmNvbTCCASIwDQYJKoZIhvcN\n" + - "AQEBBQADggEPADCCAQoCggEBAMOxbh7fZVLUB06xxNBePa9vpOuAS5km1w8ngsTu\n" + - "SvH1LZnPFd4nu40fi8bPbHd4J2oRWZ28f7LKVQgBupn9knrTQxfTV361WpmwqCcH\n" + - "MxornKyHx4t5uGrtTtX2fYoNQQk330dIKAfKpUrOiaDybB7irG2JEHdGD3Iv7ud8\n" + - "FXfXgXte26mUDX3XeCvE0pbuNKpTKApqOeojlVR6TCNB1n6KGYLMIz/1ow6XBZ64\n" + - "1zKG/9o0gSHelkUHGmGLzOAE5YpkhwzhpND9opycnfieHuy5BcoBIpeMqGNwOsGu\n" + - "p+nhFz+N8mPjSjZEf0qx+FLF2cBmNFknJJCdnV7OYfKZHE0CAwEAAaOCAu4wggLq\n" + - "MCgGA1UdEQQhMB+CHXZhbGlkLnI2LnJvb3RzLmdsb2JhbHNpZ24uY29tMA4GA1Ud\n" + - "DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0O\n" + - "BBYEFLZolpEC8/bF44e/gnh4StQ9+URwMFUGA1UdIAROMEwwBwYFZ4EMAQEwQQYJ\n" + - "KwYBBAGgMgEBMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24u\n" + - "Y29tL3JlcG9zaXRvcnkvMAwGA1UdEwEB/wQCMAAwgZoGCCsGAQUFBwEBBIGNMIGK\n" + - "MD4GCCsGAQUFBzABhjJodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9jYS9nc2F0\n" + - "bGFzcjZldnRsc2NhMjAyMDBIBggrBgEFBQcwAoY8aHR0cDovL3NlY3VyZS5nbG9i\n" + - "YWxzaWduLmNvbS9jYWNlcnQvZ3NhdGxhc3I2ZXZ0bHNjYTIwMjAuY3J0MB8GA1Ud\n" + - "IwQYMBaAFITcIQvHqF1yl4SHfvLVtvpxVk77MEYGA1UdHwQ/MD0wO6A5oDeGNWh0\n" + - "dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vY2EvZ3NhdGxhc3I2ZXZ0bHNjYTIwMjAu\n" + - "Y3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYAfT7y+I//iFVoJMLAyp5SiXkr\n" + - "xQ54CX8uapdomX4i8NcAAAF0Lsm7CwAABAMARzBFAiB0fLxAlPzkPxZOVj7c8OFc\n" + - "YwycekW0Mo+sRm/BQYoeOgIhAK2lNW7ebraH//ZlLQD7dyzWCO+kgmkQo+mqdm1x\n" + - "4P15AHUAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMAAAF0Lsm7JAAA\n" + - "BAMARjBEAiALOZvdNiA9q1Ysr7ejTGdivUqNJNm9KftmGXwHFGwf2QIgDodNLmbZ\n" + - "JFGt8l5ul0fHw2Gn8KqhRUW6CMRT58svhcswDQYJKoZIhvcNAQELBQADggIBAByb\n" + - "hoL/sArmkNjTFiEEBocMfb+brgRQdb08NKC1BDxGnfIFjUmOFzI2SVgtBmcoF8FI\n" + - "0WyXQv6ZxVE01DFZpeZpsJJYfBAjg9NR4/B7UjajvOJwQNpaciAGQ0ZzTu+SmHja\n" + - "jIiC2KqiA7Me2MoUne6hhxZ3dXEneIml8hnbTf2mjSBCVpQqyf2goslhGduPitI6\n" + - "guTtVD2PVaNCVkjlRn4Euspl2JjQWzGcEruqGyQN+Bu4yt1hsD4Jj6V9Hmzo8Vrd\n" + - "5LUxFPRGIgCUDiiwnENVsQB/D24y3IapPkojujrvsVsmQN42GIgOY5tLK/8cCziD\n" + - "vf0GzZnmL1D2ezi3TaBj+XBWFcAyF2Y9AnVRmC9CrVcp6EX0KhD4g9ZgbpJZpVlk\n" + - "G3xfOiZWTeqLnQhCMXcdcutWIwXAX5gueyF1t545vECCE4PeGZNAeWqdbrj7xaS8\n" + - "3rKQdgwF9r6p7F5HHwEVCckhovEYU4DNFzYb9n/YmC3hmskFB1keTYqydKUYEGZ5\n" + - "fvLvsjRj9xwOCqIs5j1vuKw2CaqmHxrfYaDMMSZPq/iYrOWrf72wZIvtnAHePt3X\n" + - "atQMqNbDMQrjul31ljDP9CIbbtuZSkSACyMxiC10l4uTTLQiTxtZPkwIazOjnbBe\n" + - "A4fruOEQ2k1gu5oFgqmo+xuclOKNjwd/RkK4FXnD\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.r6.roots.globalsign.com, - // O=GMO GlobalSign LTD, STREET="Springfield House, Sandling Road", OID.2.5.4.17=ME14 2LP, L=Maidstone, ST=Kent, - // C=GB, SERIALNUMBER=04705639, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB - // Issuer: CN=GlobalSign Atlas R6 EV TLS CA 2020, O=GlobalSign nv-sa, C=BE - // Serial number: 1df30d84796ac20c47da63b8e681e8f - // Valid from: Thu Aug 27 00:37:53 PDT 2020 until: Tue Sep 28 00:37:53 PDT 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHzzCCBbegAwIBAgIQAd8w2EeWrCDEfaY7jmgejzANBgkqhkiG9w0BAQsFADBV\n" + - "MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTErMCkGA1UE\n" + - "AxMiR2xvYmFsU2lnbiBBdGxhcyBSNiBFViBUTFMgQ0EgMjAyMDAeFw0yMDA4Mjcw\n" + - "NzM3NTNaFw0yMTA5MjgwNzM3NTNaMIH8MRMwEQYLKwYBBAGCNzwCAQMTAkdCMR0w\n" + - "GwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjERMA8GA1UEBRMIMDQ3MDU2Mzkx\n" + - "CzAJBgNVBAYTAkdCMQ0wCwYDVQQIDARLZW50MRIwEAYDVQQHDAlNYWlkc3RvbmUx\n" + - "ETAPBgNVBBEMCE1FMTQgMkxQMSkwJwYDVQQJDCBTcHJpbmdmaWVsZCBIb3VzZSwg\n" + - "U2FuZGxpbmcgUm9hZDEbMBkGA1UECgwSR01PIEdsb2JhbFNpZ24gTFREMSgwJgYD\n" + - "VQQDDB9yZXZva2VkLnI2LnJvb3RzLmdsb2JhbHNpZ24uY29tMIIBIjANBgkqhkiG\n" + - "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvaNcp7bzmm02Z0S92ZzJ/ul3uQWz3EnBORcI\n" + - "RuEzm0HY4t0n9DGnxpxOi/aWGX/Vj7qZC4m3G7uCE7dMy6CfXTwh4UZ+nPVijImo\n" + - "q/msJzmju/pk8HVeOEhk88yvwfzmzYLjoQagmHnDUSQULEmNWihejIh4B61qx4SI\n" + - "UoBPoBgqDfZW27HkJeqNAO6rljZTZwLenJesm2QMjebYaKxQBi3fLy0Lua2sxTik\n" + - "fbT3swEPN9xxvMomtNNM2tJwdExL2RpO8dObUe37ep6roG7gWh8NYDKMo6j9Rn9e\n" + - "f0S9jwkcRM2kZSHR09HSu8ULBgP+KYa8DDpOyt+HO+2G57MhbQIDAQABo4IC8TCC\n" + - "Au0wKgYDVR0RBCMwIYIfcmV2b2tlZC5yNi5yb290cy5nbG9iYWxzaWduLmNvbTAO\n" + - "BgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0G\n" + - "A1UdDgQWBBTa1/37G4T022LEW3WwIVV99qtjsjBVBgNVHSAETjBMMAcGBWeBDAEB\n" + - "MEEGCSsGAQQBoDIBATA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxz\n" + - "aWduLmNvbS9yZXBvc2l0b3J5LzAMBgNVHRMBAf8EAjAAMIGaBggrBgEFBQcBAQSB\n" + - "jTCBijA+BggrBgEFBQcwAYYyaHR0cDovL29jc3AuZ2xvYmFsc2lnbi5jb20vY2Ev\n" + - "Z3NhdGxhc3I2ZXZ0bHNjYTIwMjAwSAYIKwYBBQUHMAKGPGh0dHA6Ly9zZWN1cmUu\n" + - "Z2xvYmFsc2lnbi5jb20vY2FjZXJ0L2dzYXRsYXNyNmV2dGxzY2EyMDIwLmNydDAf\n" + - "BgNVHSMEGDAWgBSE3CELx6hdcpeEh37y1bb6cVZO+zBGBgNVHR8EPzA9MDugOaA3\n" + - "hjVodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2NhL2dzYXRsYXNyNmV2dGxzY2Ey\n" + - "MDIwLmNybDCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB2AG9Tdqwx8DEZ2JkApFEV\n" + - "/3cVHBHZAsEAKQaNsgiaN9kTAAABdC7aAfUAAAQDAEcwRQIgHIAHHw/Y/VKaaHhy\n" + - "rZ/cMinivfZ4lUq2ejV7FRPbT8ECIQD3RoE13/MBVMVBLCQ2ErKsB5+7F31dX/tv\n" + - "Z/muQi5UrQB2AH0+8viP/4hVaCTCwMqeUol5K8UOeAl/LmqXaJl+IvDXAAABdC7a\n" + - "AegAAAQDAEcwRQIhALl0LXt6pFqS0cHF/XkxSfDJJdhppR2eSlcMFpZY0q1PAiBJ\n" + - "YkKHqq/YD0gwtZAUEPSk54G1cLxFoUiounjya1XTRzANBgkqhkiG9w0BAQsFAAOC\n" + - "AgEAdeQotBhB7bn+CztQmF13rdBphHrGkkyHC3hL1bxkmHJcrLQ5ochqPvgdgAVq\n" + - "DXcV8zSyNwVxW6REi+uYzcsOPKo/llmgF7Psqn1t/EDcutWlykh8UwE5UaLJ2EWD\n" + - "HnIu06n47lWtAwlNMXJ/ce0oVjqsgY52Y1u54e8wFXt6lsSw02tzIC6eo1BFKxQ3\n" + - "lDKYVXgg0OvMG/C2rvH/EIq5r+st49rNGWfcWRoHsDUruChZOHwJ9PrXKBLB/QVd\n" + - "4uw2V/0ipOETDudly7yLodXP8quhet4bCEO9gweXppL/MikLrE5xt46HW1/6w+jF\n" + - "wKCHWlq4ViswlaQ8q0oY/97o2udnuDQaNdrLgW3VofMeBIMNPBgkLDicOH6bLwNf\n" + - "lV68qi1ZBxBuOdoOqQyZ9RU9d3EL50XEJ4MtUvjJRAT5EWdFaB8SGGZbD5fyza8c\n" + - "KmeO5tkZWYecLd8CKqwKcW7umPflEwOzw60Cxg6eyBYA8Jfagpbdb/kXsF6Ov8IW\n" + - "vxNdHCnXnR3oBWm2uHddESO2zGF1ZfOb0O3cHHG5nCgVkWW68VpgX/LaN90u6Dzw\n" + - "diJX7esZV5ZaniqD+flWldgAdcfeXlJ5b7I7GnFr61ycmZT/qupagUS1WDq/zfct\n" + - "QcB4QmnAzGe6kcqiDOSyIYWpiw09jha63KpJtJDWRemrlQI=\n" + - "-----END CERTIFICATE-----"; - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Thu Aug 27 00:38:11 PDT 2020", System.out); - } -} - diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoDaddyCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoDaddyCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoDaddyCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoDaddyCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,346 +0,0 @@ -/* - * Copyright (c) 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 8196141 - * @summary Interoperability tests with GoDaddy/Starfield CA - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath GoDaddyCA OCSP - * @run main/othervm -Djava.security.debug=certpath GoDaddyCA CRL - */ - -/* - * Obtain test artifacts for GoDaddy/Starfield CAs from: - * - * Go Daddy Root Certificate Authority - G2: - * valid: https://valid.gdig2.catest.godaddy.com/ - * expired: https://expired.gdig2.catest.godaddy.com/ - * revoked: https://revoked.gdig2.catest.godaddy.com/ - * - * Starfield Root Certificate Authority - G2: - * valid: https://valid.sfig2.catest.starfieldtech.com/ - * expired: https://expired.sfig2.catest.starfieldtech.com/ - * revoked: https://revoked.sfig2.catest.starfieldtech.com/ - */ -public class GoDaddyCA { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - // CRL check - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - new GoDaddyGdig2().runTest(pathValidator); - new GoDaddySfig2().runTest(pathValidator); - } -} - -class GoDaddyGdig2 { - - // Owner: CN=Go Daddy Secure Certificate Authority - G2, - // OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", - // L=Scottsdale, ST=Arizona, C=US - // Issuer: CN=Go Daddy Root Certificate Authority - G2, O="GoDaddy.com, Inc.", - // L=Scottsdale, ST=Arizona, C=US - private static final String INT = "-----BEGIN CERTIFICATE-----\n" - + "MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx\n" - + "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT\n" - + "EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp\n" - + "ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3\n" - + "MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH\n" - + "EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE\n" - + "CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD\n" - + "EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi\n" - + "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD\n" - + "BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv\n" - + "K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e\n" - + "cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY\n" - + "pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n\n" - + "eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB\n" - + "AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" - + "HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv\n" - + "9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v\n" - + "b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n\n" - + "b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG\n" - + "CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv\n" - + "MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz\n" - + "91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2\n" - + "RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi\n" - + "DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11\n" - + "GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x\n" - + "LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB\n" - + "-----END CERTIFICATE-----"; - - // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private - // Organization/serialNumber=5510922, C=US, ST=Arizona, L=Scottsdale, O=GoDaddy INC., CN=valid.gdig2.catest.godaddy.com - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHbzCCBlegAwIBAgIIC3Go9uPeseowDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV\n" + - "BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow\n" + - "GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz\n" + - "LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1\n" + - "cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTcwOTE1MjMyMzAyWhcN\n" + - "MTkwOTE1MjMyMzAyWjCB1TETMBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQB\n" + - "gjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + - "EDAOBgNVBAUTBzU1MTA5MjIxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25h\n" + - "MRMwEQYDVQQHEwpTY290dHNkYWxlMRUwEwYDVQQKEwxHb0RhZGR5IElOQy4xJzAl\n" + - "BgNVBAMTHnZhbGlkLmdkaWcyLmNhdGVzdC5nb2RhZGR5LmNvbTCCASIwDQYJKoZI\n" + - "hvcNAQEBBQADggEPADCCAQoCggEBAO3xTbLfdIHiG1MIsBCz0oIg5vBxlzZyK5Rw\n" + - "DM6A/TWUDelFWyYj6fZDXYyHby4nAK9ibfhiT2f+q+5lEslye5Mt9gC39pZbpHE2\n" + - "eyJgmtNgmPGq15pf/87JE697BRwp9CWJP3yNYeamFl/F2THZOqlXCiSRbIGZ5TsZ\n" + - "sVb1vjFPmh249Ujw1zSThY9hA669Cyp3xb4iTowjCqdNYqbn22Jbk0SEXPYzLMf0\n" + - "mlY8xZ/e/8NxzJgev3N1LR3bPEijLYDZeZJ6WKc75pqNvgo8A+dEeX9bxFkCnstY\n" + - "6Iq0HTJua0TTD6V585YXNm4Z5OxjBE5kPkkFfwW0bb5dRZp86HUCAwEAAaOCA2Aw\n" + - "ggNcMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" + - "MA4GA1UdDwEB/wQEAwIFoDA1BgNVHR8ELjAsMCqgKKAmhiRodHRwOi8vY3JsLmdv\n" + - "ZGFkZHkuY29tL2dkaWcyczMtOS5jcmwwXAYDVR0gBFUwUzBIBgtghkgBhv1tAQcX\n" + - "AzA5MDcGCCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29t\n" + - "L3JlcG9zaXRvcnkvMAcGBWeBDAEBMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcw\n" + - "AYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMEAGCCsGAQUFBzAChjRodHRwOi8v\n" + - "Y2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RpZzIuY3J0MB8G\n" + - "A1UdIwQYMBaAFEDCvSeOzDSDMKIz1/tss/C0LIDOME0GA1UdEQRGMESCHnZhbGlk\n" + - "LmdkaWcyLmNhdGVzdC5nb2RhZGR5LmNvbYIid3d3LnZhbGlkLmdkaWcyLmNhdGVz\n" + - "dC5nb2RhZGR5LmNvbTAdBgNVHQ4EFgQUKSs41O+5SnkjAEaNyHk6sxq5sn8wggF/\n" + - "BgorBgEEAdZ5AgQCBIIBbwSCAWsBaQB3AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFc\n" + - "wO+UmFXWidDdAAABXofbjGMAAAQDAEgwRgIhAPZEqPZAlYpSTx+R/+7mOUa+BcBz\n" + - "U1JHZDpcy98am0glAiEA1u2FxjgAa4L5HVGYV2LSQZIltGRJ8mBT8V0JVsdm3dsA\n" + - "dgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAV6H25ASAAAEAwBH\n" + - "MEUCIQCFowkRXyR8gkX8cL7RbPSwiKCHy/1I1WVzpinmrHlZFQIgE5nShGeK7cqT\n" + - "j2C9FfrPc/Axe3/pzAFxD/BNQD1RO5sAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb\n" + - "37jjd80OyA3cEAAAAV6H25GdAAAEAwBHMEUCIBQrE+FqILUhI0wdp2X+lf/e3UG1\n" + - "gyxHmSVeN2+CkrXPAiEA1mIIVmLNURGyI8wnZ5KRnBPOKYM2MC54RJ8CFrEHIz4w\n" + - "DQYJKoZIhvcNAQELBQADggEBADInvf3eS6SgQ1qxPx4RT2hPeU5frlWJWcOWUdZB\n" + - "6mVNcmUQMkYnjkg8+PQ782HGP0DvAfcIRDhSfXdIqzEk8MPUq1XHEOfwRzLpTiCN\n" + - "FQDQIt1LXnzESCUurJS8r4mxgaVLAwHFytOTDrQn0Xfs93dm0tnRGAg7iBg+N33V\n" + - "zOR4aqojdDUWa1Rr4WFqZMkZIxzREQCYC8HXSYqLA1oPuoMMog8dId7XSalBmGJ4\n" + - "KQVsZ0/Hpi0y9k/Zw5obGcEYJWMbuU1iaEkvdtXOiXEQfJ1WS+Yy55J4GSjpIiop\n" + - "qDZD88xA9r7ttzM/khao7jfIpVWG2HuX0JlHWdh3y9aegiw=\n" + - "-----END CERTIFICATE-----"; - - // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private - // Organization/serialNumber=5510922, C=US, ST=Arizona, L=Scottsdale, O=GoDaddy INC., CN=revoked.gdig2.catest.godaddy.com - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHdDCCBlygAwIBAgIIEBJV3vmogM8wDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV\n" + - "BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow\n" + - "GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz\n" + - "LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1\n" + - "cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTcwOTE1MjMyMzAzWhcN\n" + - "MTkwOTE1MjMyMzAzWjCB1zETMBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQB\n" + - "gjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + - "EDAOBgNVBAUTBzU1MTA5MjIxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25h\n" + - "MRMwEQYDVQQHEwpTY290dHNkYWxlMRUwEwYDVQQKEwxHb0RhZGR5IElOQy4xKTAn\n" + - "BgNVBAMTIHJldm9rZWQuZ2RpZzIuY2F0ZXN0LmdvZGFkZHkuY29tMIIBIjANBgkq\n" + - "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCuBsAR2XGf05mYOuag+0aS4lBuLO5/f\n" + - "kEO7KNo7BcdY7J78yXYRYW0jGnV29bjrQZJfu5yv5bU+OjTIDVbCWZAwtBXEKrJj\n" + - "riIOUXi3hXphtlyMMAaiXQoA84jwS634DsD0w6XUUP2Lem8jC3RudjvmkDQHoY3M\n" + - "uhhS7jLxKnYKnXbLwlqxpdwmEgbqIb5DN5snLAyinTkALLVWZ6RneIuSjhKWbuef\n" + - "cEKFScHm6SFsKraltV/T17SWi6zQd/AypKA8JeWXD9WZcsSR9z/41VMJbvTeuP+d\n" + - "ZBA4dqPsBTl4N4i54rNEyzMyxDwdvIGrJJ+FVRMKoYjuUi5wY9zO4QIDAQABo4ID\n" + - "YzCCA18wDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH\n" + - "AwIwDgYDVR0PAQH/BAQDAgWgMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9jcmwu\n" + - "Z29kYWRkeS5jb20vZ2RpZzJzMy05LmNybDBcBgNVHSAEVTBTMEgGC2CGSAGG/W0B\n" + - "BxcDMDkwNwYIKwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j\n" + - "b20vcmVwb3NpdG9yeS8wBwYFZ4EMAQEwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUF\n" + - "BzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6\n" + - "Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZGlnMi5jcnQw\n" + - "HwYDVR0jBBgwFoAUQMK9J47MNIMwojPX+2yz8LQsgM4wUQYDVR0RBEowSIIgcmV2\n" + - "b2tlZC5nZGlnMi5jYXRlc3QuZ29kYWRkeS5jb22CJHd3dy5yZXZva2VkLmdkaWcy\n" + - "LmNhdGVzdC5nb2RhZGR5LmNvbTAdBgNVHQ4EFgQUCJELlWq8+ntmR5JTjmZMG+HI\n" + - "e5EwggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB1AFYUBpov18Ls0/XhvUSyPsdG\n" + - "drm8mRFcwO+UmFXWidDdAAABXofbk3cAAAQDAEYwRAIgHo8UllsN8FcaF16xx7kT\n" + - "vQU1wM7qUKnhN38/z8dU4QUCIFrzGJyajoVPQ2fzOTb9ygzA7T3wqsnT3ML5/KJ6\n" + - "+6+CAHYA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFeh9uXHQAA\n" + - "BAMARzBFAiEA5DENZZT7SBxNRvo9yFHNNeWqH2d4uqGUwc1rKILrMGsCIHZ3N4dZ\n" + - "zv/J+7fbLP1nrAmdUT92ow1bhtMPuq2PfXsAAHcApLkJkLQYWBSHuxOizGdwCjw1\n" + - "mAT5G9+443fNDsgN3BAAAAFeh9uYjAAABAMASDBGAiEAyY8ylnGHiH5L3yXE7BsH\n" + - "v75ja2RtuuYbMADAlDK/ZDoCIQDwuCq3x+egpB/GISxTnwkrDwhNhhIJNyk5F4j1\n" + - "/J8A0DANBgkqhkiG9w0BAQsFAAOCAQEAMGot6gBZ77HIDMb1n/HPrKdSHN0ngq7Z\n" + - "rhrkgbp+mH1Cs1lZA3qldMDxKXgNiodFqU/e4VewasQ9tJMmDXrTZIHualJGmIvq\n" + - "ISvV0ZUfSW/sJmo0ZDw8iBM993LDkA4wSc6SunhjOwu3LBfl9aKkeq6IhUEAG8X7\n" + - "54oO4iApt+APLMyeV9lZ/T7MGVbAjwdm+T1RMa/Ca99BahaRWN7hiM+zS3Ly+l6G\n" + - "7kqAkBFuJWbbZImADZ2RPldY6hBzTk6MT2hLCV40UD8JqwJo+qq7nGfJdTaFyZI6\n" + - "nJvrVATO7jL64YFP3xlVi8EQaCeKdZdn+BCCNA/ja0mWMj8EU9Islg==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, null, System.out); - } -} - -class GoDaddySfig2 { - - // Owner: CN=Starfield Secure Certificate Authority - G2, - // OU=http://certs.starfieldtech.com/repository/, O="Starfield Technologies, Inc.", - // L=Scottsdale, ST=Arizona, C=US - // Issuer: CN=Starfield Root Certificate Authority - G2, - // O="Starfield Technologies, Inc.", L=Scottsdale, ST=Arizona, C=US - private static final String INT = "-----BEGIN CERTIFICATE-----\n" - + "MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n" - + "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n" - + "HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs\n" - + "ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw\n" - + "MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\n" - + "b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj\n" - + "aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk\n" - + "dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg\n" - + "Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" - + "DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF\n" - + "pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE\n" - + "3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV\n" - + "Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+\n" - + "MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX\n" - + "v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB\n" - + "Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+\n" - + "zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB\n" - + "BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo\n" - + "LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo\n" - + "LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF\n" - + "BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv\n" - + "MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN\n" - + "QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0\n" - + "rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO\n" - + "eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ\n" - + "sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ\n" - + "7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7\n" - + "-----END CERTIFICATE-----"; - - // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Arizona/businessCategory=Private - // Organization/serialNumber=R17247416, C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, LLC, - // CN=valid.sfig2.catest.starfieldtech.com - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHuzCCBqOgAwIBAgIIaZoUcUIjkGwwDQYJKoZIhvcNAQELBQAwgcYxCzAJBgNV\n" + - "BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUw\n" + - "IwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypo\n" + - "dHRwOi8vY2VydHMuc3RhcmZpZWxkdGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNV\n" + - "BAMTK1N0YXJmaWVsZCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIw\n" + - "HhcNMTcwOTE3MDM0ODAxWhcNMTkwOTE3MDM0ODAxWjCB6zETMBEGCysGAQQBgjc8\n" + - "AgEDEwJVUzEYMBYGCysGAQQBgjc8AgECEwdBcml6b25hMR0wGwYDVQQPExRQcml2\n" + - "YXRlIE9yZ2FuaXphdGlvbjESMBAGA1UEBRMJUjE3MjQ3NDE2MQswCQYDVQQGEwJV\n" + - "UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEkMCIGA1UE\n" + - "ChMbU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgTExDMS0wKwYDVQQDEyR2YWxpZC5z\n" + - "ZmlnMi5jYXRlc3Quc3RhcmZpZWxkdGVjaC5jb20wggEiMA0GCSqGSIb3DQEBAQUA\n" + - "A4IBDwAwggEKAoIBAQDVxhI45IQtNrJuun7HU8v2CKg/h/euysft2VrRsaGSMAln\n" + - "V6TtpWj2UGm7OmzE2NNzOhD9JJQSc1W6aHEsCTVJ148sgldFFmP39cboBFoLCFlJ\n" + - "DxsVGeyKu+KlDKq7Vp2+ty3TeFNOBXEVtEc8SsC8mVjsk2VWW7X/fCVFYEzzyPUI\n" + - "sJPWahNOW2wVxNWKeW5jwzeNMOFVQiT9+YpZVQnV06uK3rPd9tVYU5SfdfPVpScY\n" + - "/O/tyZyflTGuXZ+YXn1CYRsOq3VypVFfhXunV5prQ/vTnyjddVWce1wwoUT5DvFO\n" + - "/0vcWolHktiOAJkmAiGRfHvjhxW8mkjKqaMnstKRAgMBAAGjggOEMIIDgDAMBgNV\n" + - "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8B\n" + - "Af8EBAMCBaAwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0\n" + - "ZWNoLmNvbS9zZmlnMnMzLTEuY3JsMGIGA1UdIARbMFkwTgYLYIZIAYb9bgEHFwMw\n" + - "PzA9BggrBgEFBQcCARYxaHR0cDovL2NlcnRpZmljYXRlcy5zdGFyZmllbGR0ZWNo\n" + - "LmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBATCBggYIKwYBBQUHAQEEdjB0MCoGCCsG\n" + - "AQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNoLmNvbS8wRgYIKwYBBQUH\n" + - "MAKGOmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuc3RhcmZpZWxkdGVjaC5jb20vcmVwb3Np\n" + - "dG9yeS9zZmlnMi5jcnQwHwYDVR0jBBgwFoAUJUWBaFAmOD07LSy+zWrZtj2zZmMw\n" + - "WQYDVR0RBFIwUIIkdmFsaWQuc2ZpZzIuY2F0ZXN0LnN0YXJmaWVsZHRlY2guY29t\n" + - "gih3d3cudmFsaWQuc2ZpZzIuY2F0ZXN0LnN0YXJmaWVsZHRlY2guY29tMB0GA1Ud\n" + - "DgQWBBTxiYdHMn55sMWTFgp7xif7ludWTjCCAX4GCisGAQQB1nkCBAIEggFuBIIB\n" + - "agFoAHcAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFejfR7OAAA\n" + - "BAMASDBGAiEA/s7a5OGhtaCutT1l4KNE7dUbM3WGUExG/ZJ+Y6IH3nUCIQCvpVJf\n" + - "Y0XBInIUv391hNzSEhv6nvIBEjZtKdvGcP8/5QB2AO5Lvbd1zmC64UJpH6vhnmaj\n" + - "D35fsHLYgwDEe4l6qP3LAAABXo30fxEAAAQDAEcwRQIhANqG9yfi3ax0pTnwr4Ti\n" + - "wVfUrZclJDS06ePkTHppLkLTAiBTRKkVf1df4Irvmd7neT1wdS2fhDxmnVIYAN5J\n" + - "6tOGDQB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABXo30gFsA\n" + - "AAQDAEYwRAIgb8Xc54M+QD4wfSWLj5Ae/wrSEgRp7Kbf4Lf4vT4W0usCIGAShkJI\n" + - "CRxoudQDRxooNJhfXgsTB8QhwFC9PUPo3ZV+MA0GCSqGSIb3DQEBCwUAA4IBAQBt\n" + - "TqvwxqrkPYm/ssbN9cpVWlrQPw3DblsAEV6gnrrTJMd7HB042H3HLUiitddRjO40\n" + - "0EJM/tUOSGcWfqnJHWFDKoWzdrF5lHAzSRkMjdXgY9TTN5K5tUMEpfRjtink/zoY\n" + - "pNyc5ua4SXn94KfMZcOYGRvUM+0q6vLRBBMH541E3M6q6JbEBqZJFY8gBWwYqHH0\n" + - "xNGahm5++v4trFFCJzSfvfV1v+rnqy8tRivi7ZFLXWCcSyAqMH+T9Q36lKeFtaw4\n" + - "Sapf+dh2yrd2IBLW5eaAD13nCAjO/W0GuC7zw4+4mhW5+DTVJXrCkK5XddkVLhML\n" + - "k5pMoIv5EsFIm0Cs+DfF\n" + - "-----END CERTIFICATE-----"; - - // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Arizona/businessCategory=Private - // Organization/serialNumber=R17247416, C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, LLC, - // CN=revoked.sfig2.catest.starfieldtech.com - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHwTCCBqmgAwIBAgIJAPc1qVz+WDxpMA0GCSqGSIb3DQEBCwUAMIHGMQswCQYD\n" + - "VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEl\n" + - "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEzMDEGA1UECxMq\n" + - "aHR0cDovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkvMTQwMgYD\n" + - "VQQDEytTdGFyZmllbGQgU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcy\n" + - "MB4XDTE3MDkxOTEzMDkwMVoXDTE5MDkxOTEzMDkwMVowge0xEzARBgsrBgEEAYI3\n" + - "PAIBAxMCVVMxGDAWBgsrBgEEAYI3PAIBAhMHQXJpem9uYTEdMBsGA1UEDxMUUHJp\n" + - "dmF0ZSBPcmdhbml6YXRpb24xEjAQBgNVBAUTCVIxNzI0NzQxNjELMAkGA1UEBhMC\n" + - "VVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJDAiBgNV\n" + - "BAoTG1N0YXJmaWVsZCBUZWNobm9sb2dpZXMsIExMQzEvMC0GA1UEAxMmcmV2b2tl\n" + - "ZC5zZmlnMi5jYXRlc3Quc3RhcmZpZWxkdGVjaC5jb20wggEiMA0GCSqGSIb3DQEB\n" + - "AQUAA4IBDwAwggEKAoIBAQCWsAZC9goWW6yzg9HiLjCG4Gv2PCHlUIQGqyhc1y9a\n" + - "YZVXUI27/NhHjNNMTwP9TKmncrxnGaTZ9+ZCS1JlSgsNYQcLKKZW+SiEOzwpOfwV\n" + - "dOCSWrt/EDyJHktx3VIbfi+mD7dvzH3B/iGxMrmdCGIy3xiVAc7MkfsWzcLlPUP3\n" + - "oUpPBYyzWqZ2tVsBDigoirERFqZNfHZ7ZNMnn8FcmAt7udKjAAewNRlwzR7ZVp5s\n" + - "f5pbnRlRikF30msSHVJoPBICEYmzCxUI+zFlDBjf4vlJojwV0/Rfq85it2yhN/MV\n" + - "we2IBC+z9FAAogYo+JFw7Uxq8nsLCKX1tTPsqxGXWNonAgMBAAGjggOHMIIDgzAM\n" + - "BgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNV\n" + - "HQ8BAf8EBAMCBaAwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmll\n" + - "bGR0ZWNoLmNvbS9zZmlnMnMzLTEuY3JsMGIGA1UdIARbMFkwTgYLYIZIAYb9bgEH\n" + - "FwMwPzA9BggrBgEFBQcCARYxaHR0cDovL2NlcnRpZmljYXRlcy5zdGFyZmllbGR0\n" + - "ZWNoLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBATCBggYIKwYBBQUHAQEEdjB0MCoG\n" + - "CCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNoLmNvbS8wRgYIKwYB\n" + - "BQUHMAKGOmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuc3RhcmZpZWxkdGVjaC5jb20vcmVw\n" + - "b3NpdG9yeS9zZmlnMi5jcnQwHwYDVR0jBBgwFoAUJUWBaFAmOD07LSy+zWrZtj2z\n" + - "ZmMwXQYDVR0RBFYwVIImcmV2b2tlZC5zZmlnMi5jYXRlc3Quc3RhcmZpZWxkdGVj\n" + - "aC5jb22CKnd3dy5yZXZva2VkLnNmaWcyLmNhdGVzdC5zdGFyZmllbGR0ZWNoLmNv\n" + - "bTAdBgNVHQ4EFgQU9hCSl7QoQ8KdsGgwMDwlvSurKNcwggF9BgorBgEEAdZ5AgQC\n" + - "BIIBbQSCAWkBZwB1AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFcwO+UmFXWidDdAAAB\n" + - "XppC0cEAAAQDAEYwRAIgIO8sIG88JlA73P2myZ7EshemxaR8qBgf3wlYZpg5aZEC\n" + - "IGtlcUL7Il1uOLN0LTAzNTQ7pfb7oFYbr0R4LWe2ZvBIAHYA7ku9t3XOYLrhQmkf\n" + - "q+GeZqMPfl+wctiDAMR7iXqo/csAAAFemkLVbwAABAMARzBFAiEAmWkzcotxZSwb\n" + - "xPS3MG13TVXGu2+MiXXjOIf42DR8zJQCIBL4cSOJh+LX5kpPub6KOiEOn7TVE1Zv\n" + - "IQUxuf+vyAD4AHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFe\n" + - "mkLXRQAABAMARzBFAiBX8foh/KrYr34O2c9cH6uyWW2XjBHNLsYX1mr+8VuNaAIh\n" + - "AObDQwpDYh/bNp6k547gDxnR73LeU3kvl1Y76GjgxLAhMA0GCSqGSIb3DQEBCwUA\n" + - "A4IBAQDJ5vlagzOH8/ORUMgT33muSDFXCe5el/sQzVg8dridw9qjnxOpkGibdCiT\n" + - "b9Il1bdi7UnG8MlA3XpDjGgp6J/mUTijD9WcFx4lp5JnPaIbShHWCyIlRVZJzrZc\n" + - "UYhR56xXOKDYKYOIvM6qTqegXyEynJrIVTArMk7jQf0oNQLLHzXE1fVS1zut0H5l\n" + - "GE+TBgjasMEa1o1e/H/heSytb2zFNsZr8oxojzGBmlKyfCoIIcCv3PxX2ur57zJE\n" + - "9ADWoYK/7gYVba0JmLV4nQltDPp06nOYT9imxBWTrFahgPx1jOQDLgIpitkjyCy4\n" + - "xpmxUk8L6yc3O3aSD9OU/fzk/t/d\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, null, System.out); - } -} - diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,621 +0,0 @@ -/* - * 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 8307134 - * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath GoogleCA OCSP - * @run main/othervm -Djava.security.debug=certpath GoogleCA CRL - */ - -/* - * Obtain TLS test artifacts for Google CAs from: - * - * https://pki.goog/repository/ - */ -public class GoogleCA { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - boolean ocspEnabled = false; - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - ocspEnabled = true; - } - - new GoogleGSR4().runTest(pathValidator); - new GoogleGTSR1().runTest(pathValidator); - new GoogleGTSR2().runTest(pathValidator); - new GoogleGTSR3().runTest(pathValidator); - new GoogleGTSR4().runTest(pathValidator); - } -} - -class GoogleGSR4 { - - // Owner: CN=GTS CA 2D4, O=Google Trust Services LLC, C=US - // Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign ECC Root CA - R4 - // Serial number: 21668f1cd0a2a8f847d8aad34 - // Valid from: Tue Oct 04 17:00:42 PDT 2022 until: Wed Sep 29 17:00:42 PDT 2027 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIDBDCCAqugAwIBAgINAhZo8c0KKo+EfYqtNDAKBggqhkjOPQQDAjBQMSQwIgYD\n" + - "VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh\n" + - "bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMjIxMDA1MDAwMDQyWhcNMjcw\n" + - "OTMwMDAwMDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0\n" + - "IFNlcnZpY2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDJENDBZMBMGByqGSM49AgEG\n" + - "CCqGSM49AwEHA0IABPQdCdV61990MPueGTVpXAjRmp2JIxt0Yuy59RZYT/XKg1lN\n" + - "gpRc0eh/bHtpehigtqe+llKTiVEkMhSMURoQQsOjggFyMIIBbjAOBgNVHQ8BAf8E\n" + - "BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQI\n" + - "MAYBAf8CAQAwHQYDVR0OBBYEFKiI2Yo5rGXVgks3qJVsZUPNRAHgMB8GA1UdIwQY\n" + - "MBaAFFSwe61FuOJAf/sKbvu+M8k8o4TVMGYGCCsGAQUFBwEBBFowWDAlBggrBgEF\n" + - "BQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyNDAvBggrBgEFBQcwAoYjaHR0\n" + - "cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3NyNC5kZXIwMgYDVR0fBCswKTAnoCWg\n" + - "I4YhaHR0cDovL2NybC5wa2kuZ29vZy9nc3I0L2dzcjQuY3JsME0GA1UdIARGMEQw\n" + - "CAYGZ4EMAQIBMDgGCisGAQQB1nkCBQMwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9w\n" + - "a2kuZ29vZy9yZXBvc2l0b3J5LzAKBggqhkjOPQQDAgNHADBEAiBi+ikli1YBHQGs\n" + - "b5mnyBo5mydw04o386BPgaPpiBzgagIgbcpwQJCalLIekv8XRMoWFr3nV5XJfWRU\n" + - "5QPpOX0rXbg=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.gsr4.demo.pki.goog - // Issuer: CN=GTS CA 2D4, O=Google Trust Services LLC, C=US - // Serial number: 4c435754ee6e013c10efaff908a58cbb - // Valid from: Mon Mar 27 12:41:45 PDT 2023 until: Sun Jun 25 12:41:44 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIEsTCCBFegAwIBAgIQTENXVO5uATwQ76/5CKWMuzAKBggqhkjOPQQDAjBGMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzET\n" + - "MBEGA1UEAxMKR1RTIENBIDJENDAeFw0yMzAzMjcxOTQxNDVaFw0yMzA2MjUxOTQx\n" + - "NDRaMCIxIDAeBgNVBAMTF2dvb2QuZ3NyNC5kZW1vLnBraS5nb29nMIIBIjANBgkq\n" + - "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAymtcnnxJ8pSF4YJUKTWKcHbRw28ShLzo\n" + - "KVTRPUsRrZZDqyDx296k3e0D04kBhcvEduxtEabCe89m06SH7L+bGVi25j35AXwn\n" + - "6aziLs/EV4BRy9ACfYipeT5PnQbaMmVe65q/RYKmWqD/z0SEh2uMFxRVl1CBmS/J\n" + - "owbNUlrEEDiYkE/nGfCmacpW0QZ7kxGjSR34mCSDugIYE/HME3ZVcZOVf2LT0lBA\n" + - "DhQtZI6cXy2lO8Ro/dUtcZKjo8iu0xW1pQeiJq9+CGp62MJFmpl+EfzP/B8aXQiF\n" + - "+m44LJJgAjiShAwVo9HbJUYv0dqCS9G22FL43xXqAdDlWZeuZyg7bQIDAQABo4IC\n" + - "fjCCAnowDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1Ud\n" + - "EwEB/wQCMAAwHQYDVR0OBBYEFKMuYkTnbWyrTBfBqbNNe91z3GPjMB8GA1UdIwQY\n" + - "MBaAFKiI2Yo5rGXVgks3qJVsZUPNRAHgMHgGCCsGAQUFBwEBBGwwajA1BggrBgEF\n" + - "BQcwAYYpaHR0cDovL29jc3AucGtpLmdvb2cvcy9ndHMyZDQvS2tnczU5VFFIelkw\n" + - "MQYIKwYBBQUHMAKGJWh0dHA6Ly9wa2kuZ29vZy9yZXBvL2NlcnRzL2d0czJkNC5k\n" + - "ZXIwIgYDVR0RBBswGYIXZ29vZC5nc3I0LmRlbW8ucGtpLmdvb2cwIQYDVR0gBBow\n" + - "GDAIBgZngQwBAgEwDAYKKwYBBAHWeQIFAzA8BgNVHR8ENTAzMDGgL6AthitodHRw\n" + - "Oi8vY3Jscy5wa2kuZ29vZy9ndHMyZDQvSUlXMzNMVUVwV3cuY3JsMIIBBAYKKwYB\n" + - "BAHWeQIEAgSB9QSB8gDwAHcA6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0G\n" + - "vW4AAAGHJM62ygAABAMASDBGAiEAkeiqmfYYCVEmGA12/RJUZPdmxRP2ZXF0Xm30\n" + - "Oz+q2tgCIQCgSYqT/6RH+PCOauOVW4uaoshT+HfqurghVCzwGgBFvwB1ALc++yTf\n" + - "nE26dfI5xbpY9Gxd/ELPep81xJ4dCYEl7bSZAAABhyTOttoAAAQDAEYwRAIgBXao\n" + - "3Pry1nCHu3bngW3q3CHSLzmNHmO4cXMSdN2sAOkCIDE5DUyok3TRsOIHu1QTB0R2\n" + - "UxPeFm9KS73TBT8JEZykMAoGCCqGSM49BAMCA0gAMEUCIG1m91VOq3tghyLPA6YR\n" + - "/Pkq+gQylyM8wGJgnRMRE0lhAiEAxBgYXImtVqbfymq2MYwhV9KmG9gPIfqN6qWi\n" + - "lzblUM0=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.gsr4.demo.pki.goog - // Issuer: CN=GTS CA 2D4, O=Google Trust Services LLC, C=US - // Serial number: 1f9bd55e26716b3710b2614cec6fff02 - // Valid from: Mon Mar 27 12:48:37 PDT 2023 until: Sun Jun 25 12:48:36 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIEtzCCBFygAwIBAgIQH5vVXiZxazcQsmFM7G//AjAKBggqhkjOPQQDAjBGMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzET\n" + - "MBEGA1UEAxMKR1RTIENBIDJENDAeFw0yMzAzMjcxOTQ4MzdaFw0yMzA2MjUxOTQ4\n" + - "MzZaMCUxIzAhBgNVBAMTGnJldm9rZWQuZ3NyNC5kZW1vLnBraS5nb29nMIIBIjAN\n" + - "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApVuoZ/bS9c2WSQ8W1FjPEsdGoANj\n" + - "PqKaPwdyUhnko9ayyGGi5hHLYqir2tiNjfO8i5e3ybe6CIaybY37SQebquV+rioH\n" + - "O9BS75GgtYXCaMK/8prya9RiaUjy7kecvpKtJNiaXrLJy8Vzq9g39n9hiXJYMGkc\n" + - "fCWYjWd5jU4pAsYTslmuIYoIZuwRRX34iET6Brs3ijykcmYtG5F90wqFlvRxRh0x\n" + - "vD0EeTOLGZSDQMYxlhfrqG449I10iTHusSxI2AXB6k7N2UXMJ44D7Z3RWkv1ItsY\n" + - "eKVXQyLAYd8YYTFNdGa75SoRr+ChFbLCgSUMg188T/SS013bH/XSHpCbQQIDAQAB\n" + - "o4ICgDCCAnwwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwG\n" + - "A1UdEwEB/wQCMAAwHQYDVR0OBBYEFLXeKzKKPx+Vs7YEKdmz9Vur9BZiMB8GA1Ud\n" + - "IwQYMBaAFKiI2Yo5rGXVgks3qJVsZUPNRAHgMHgGCCsGAQUFBwEBBGwwajA1Bggr\n" + - "BgEFBQcwAYYpaHR0cDovL29jc3AucGtpLmdvb2cvcy9ndHMyZDQvaG5fZHY1dHlS\n" + - "SVkwMQYIKwYBBQUHMAKGJWh0dHA6Ly9wa2kuZ29vZy9yZXBvL2NlcnRzL2d0czJk\n" + - "NC5kZXIwJQYDVR0RBB4wHIIacmV2b2tlZC5nc3I0LmRlbW8ucGtpLmdvb2cwIQYD\n" + - "VR0gBBowGDAIBgZngQwBAgEwDAYKKwYBBAHWeQIFAzA8BgNVHR8ENTAzMDGgL6At\n" + - "hitodHRwOi8vY3Jscy5wa2kuZ29vZy9ndHMyZDQvSUlXMzNMVUVwV3cuY3JsMIIB\n" + - "AwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYAejKMVNi3LbYg6jjgUh7phBZwMhOFTTvS\n" + - "K8E6V6NS61IAAAGHJNUx1gAABAMARzBFAiEAj/RgXx1ScnsOf9R9N3eyPMJtH33C\n" + - "mOrRCOodG8QXmE0CIHwNJC5E53BVmfMzZwJH9f2BiUx31SGHWFvG283zVtX/AHUA\n" + - "6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4AAAGHJNUxnAAABAMARjBE\n" + - "AiAI7pcrKatsz0G4QYPKmS74VQVEgnHqgKSoqv0ghTJXTgIgPyoYubz4MEHYirBu\n" + - "69BLC2jioXr8+wS7MK1IPqjdH44wCgYIKoZIzj0EAwIDSQAwRgIhAI4NdZ5JwTuW\n" + - "P+RH2bsAc5xrb804G9mOc3WMRVxTUKesAiEA/jHMJ2YdPv0WXKjKY7nUyFjUPdin\n" + - "BHRHfBeltynaFzU=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon Mar 27 13:49:33 PDT 2023", System.out); - } -} - -class GoogleGTSR1 { - - // Owner: CN=GTS CA 1D4, O=Google Trust Services LLC, C=US - // Issuer: CN=GTS Root R1, O=Google Trust Services LLC, C=US - // Serial number: 2008eb2023336658b64cddb9b - // Valid from: Wed Aug 12 17:00:42 PDT 2020 until: Wed Sep 29 17:00:42 PDT 2027 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIFjDCCA3SgAwIBAgINAgCOsgIzNmWLZM3bmzANBgkqhkiG9w0BAQsFADBHMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\n" + - "MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw\n" + - "MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\n" + - "Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFENDCCASIwDQYJKoZIhvcNAQEBBQAD\n" + - "ggEPADCCAQoCggEBAKvAqqPCE27l0w9zC8dTPIE89bA+xTmDaG7y7VfQ4c+mOWhl\n" + - "UebUQpK0yv2r678RJExK0HWDjeq+nLIHN1Em5j6rARZixmyRSjhIR0KOQPGBMUld\n" + - "saztIIJ7O0g/82qj/vGDl//3t4tTqxiRhLQnTLXJdeB+2DhkdU6IIgx6wN7E5NcU\n" + - "H3Rcsejcqj8p5Sj19vBm6i1FhqLGymhMFroWVUGO3xtIH91dsgy4eFKcfKVLWK3o\n" + - "2190Q0Lm/SiKmLbRJ5Au4y1euFJm2JM9eB84Fkqa3ivrXWUeVtye0CQdKvsY2Fka\n" + - "zvxtxvusLJzLWYHk55zcRAacDA2SeEtBbQfD1qsCAwEAAaOCAXYwggFyMA4GA1Ud\n" + - "DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T\n" + - "AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUJeIYDrJXkZQq5dRdhpCD3lOzuJIwHwYD\n" + - "VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG\n" + - "CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw\n" + - "AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt\n" + - "MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsME0G\n" + - "A1UdIARGMEQwCAYGZ4EMAQIBMDgGCisGAQQB1nkCBQMwKjAoBggrBgEFBQcCARYc\n" + - "aHR0cHM6Ly9wa2kuZ29vZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAgEA\n" + - "IVToy24jwXUr0rAPc924vuSVbKQuYw3nLflLfLh5AYWEeVl/Du18QAWUMdcJ6o/q\n" + - "FZbhXkBH0PNcw97thaf2BeoDYY9Ck/b+UGluhx06zd4EBf7H9P84nnrwpR+4GBDZ\n" + - "K+Xh3I0tqJy2rgOqNDflr5IMQ8ZTWA3yltakzSBKZ6XpF0PpqyCRvp/NCGv2KX2T\n" + - "uPCJvscp1/m2pVTtyBjYPRQ+QuCQGAJKjtN7R5DFrfTqMWvYgVlpCJBkwlu7+7KY\n" + - "3cTIfzE7cmALskMKNLuDz+RzCcsYTsVaU7Vp3xL60OYhqFkuAOOxDZ6pHOj9+OJm\n" + - "YgPmOT4X3+7L51fXJyRH9KfLRP6nT31D5nmsGAOgZ26/8T9hsBW1uo9ju5fZLZXV\n" + - "VS5H0HyIBMEKyGMIPhFWrlt/hFS28N1zaKI0ZBGD3gYgDLbiDT9fGXstpk+Fmc4o\n" + - "lVlWPzXe81vdoEnFbr5M272HdgJWo+WhT9BYM0Ji+wdVmnRffXgloEoluTNcWzc4\n" + - "1dFpgJu8fF3LG0gl2ibSYiCi9a6hvU0TppjJyIWXhkJTcMJlPrWx1VytEUGrX2l0\n" + - "JDwRjW/656r0KVB02xHRKvm2ZKI03TglLIpmVCK3kBKkKNpBNkFt8rhafcCKOb9J\n" + - "x/9tpNFlQTl7B39rJlJWkR17QnZqVptFePFORoZmFzM=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.gtsr1.demo.pki.goog - // Issuer: CN=GTS CA 1D4, O=Google Trust Services LLC, C=US - // Serial number: 19c08d5cde41fc84108f54c8d2a1aeca - // Valid from: Mon Mar 27 12:33:43 PDT 2023 until: Sun Jun 25 12:33:42 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFcjCCBFqgAwIBAgIQGcCNXN5B/IQQj1TI0qGuyjANBgkqhkiG9w0BAQsFADBG\n" + - "MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\n" + - "QzETMBEGA1UEAxMKR1RTIENBIDFENDAeFw0yMzAzMjcxOTMzNDNaFw0yMzA2MjUx\n" + - "OTMzNDJaMCMxITAfBgNVBAMTGGdvb2QuZ3RzcjEuZGVtby5wa2kuZ29vZzCCASIw\n" + - "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMkOYhMM6kQMlep+l2/l5KTC1ow8\n" + - "nXHwXQzugR2Js302pM3p2UCfnfhlK0a9UUSVtAZa8ydVUyVRF9LzW1rOIK8UdlEj\n" + - "O6qAvPnPw8laY7rCPWRPibxu0OqL/5sYD+a4hQ7GhVsYDXXxnWQvLV5mppRlYF/8\n" + - "80ugGggRb+U3y6V84f1JnwSMvZFULe19BOeV5qWAHHFfgy0zePzcDMy8AqxaVBOb\n" + - "FVSsbdql2gnRyC4WZ9D5lc8vwS84KrJbce2+VtrpcKVALtyVA0Zzor2lr2wOVc4i\n" + - "OOwMNk9948eStAjOV8N4B1h9D/pd+cFSWfgXufr5ZClwijLr3zLvZxDGI6ECAwEA\n" + - "AaOCAn0wggJ5MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAM\n" + - "BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSTKR+0ebWnH3uGz5qju5/LpkCjYzAfBgNV\n" + - "HSMEGDAWgBQl4hgOsleRlCrl1F2GkIPeU7O4kjB4BggrBgEFBQcBAQRsMGowNQYI\n" + - "KwYBBQUHMAGGKWh0dHA6Ly9vY3NwLnBraS5nb29nL3MvZ3RzMWQ0L3B6OThKdFZT\n" + - "RnRjMDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMx\n" + - "ZDQuZGVyMCMGA1UdEQQcMBqCGGdvb2QuZ3RzcjEuZGVtby5wa2kuZ29vZzAhBgNV\n" + - "HSAEGjAYMAgGBmeBDAECATAMBgorBgEEAdZ5AgUDMDwGA1UdHwQ1MDMwMaAvoC2G\n" + - "K2h0dHA6Ly9jcmxzLnBraS5nb29nL2d0czFkNC92My1EUW1sYi1ZWS5jcmwwggEC\n" + - "BgorBgEEAdZ5AgQCBIHzBIHwAO4AdQC3Pvsk35xNunXyOcW6WPRsXfxCz3qfNcSe\n" + - "HQmBJe20mQAAAYckx1OMAAAEAwBGMEQCICQ4Do1cKFsqmm/swKZkdM/qGluDbctL\n" + - "tIgp0YnoZTlEAiByAeAEaVQiU27AnpUerimnjPnThQq26vqvnWdstb0mwgB1AK33\n" + - "vvp8/xDIi509nB4+GGq0Zyldz7EMJMqFhjTr3IKKAAABhyTHU7UAAAQDAEYwRAIg\n" + - "WAIAOov42kcgOj0rYO3qb4/HTsW3o69x4IKd8ycsaVkCICIQUaeKwNp4aW/civO9\n" + - "No/v5Ner5bmlwheqFAJcR/HCMA0GCSqGSIb3DQEBCwUAA4IBAQBEKKdwuzuAhdir\n" + - "3hbPQIosD6H9vatr8tExWCDmw+PHOoiWIUTBu5fVZPQ27EgehTIA6kNhQj2g7fkF\n" + - "Bd5zAl4k7WdsDZCeOHml6XXQZHvc+p4DYBKTTt3h81lsMLw8aWCOaiSmrQ0hZS/E\n" + - "iuaqvlOFpOTd0x+MN2qcU14hi8SKxBgpraqR/s7OCwUFltxcPq0GAybzDGc9lgB+\n" + - "Jt56QviN641s7hxThyGhFIHSePgWuwbT1grJKQiSW35yI4PJO90HoCpd2MLrC5Ic\n" + - "B89ykY8mQcx+naGPZQdwdpx9GvKwSZdn+cq3kZwD66iXnwhqmiEdq4eBZr8ygSya\n" + - "lnGV2OW+\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.gtsr1.demo.pki.goog - // Issuer: CN=GTS CA 1D4, O=Google Trust Services LLC, C=US - // Serial number: c414c34e6c2cc66c102b8d3502be3bb4 - // Valid from: Mon Mar 27 12:42:39 PDT 2023 until: Sun Jun 25 12:42:38 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIFfDCCBGSgAwIBAgIRAMQUw05sLMZsECuNNQK+O7QwDQYJKoZIhvcNAQELBQAw\n" + - "RjELMAkGA1UEBhMCVVMxIjAgBgNVBAoTGUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBM\n" + - "TEMxEzARBgNVBAMTCkdUUyBDQSAxRDQwHhcNMjMwMzI3MTk0MjM5WhcNMjMwNjI1\n" + - "MTk0MjM4WjAmMSQwIgYDVQQDExtyZXZva2VkLmd0c3IxLmRlbW8ucGtpLmdvb2cw\n" + - "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCOeL80aphh8K8Cz41Sl2Cv\n" + - "cI3Elrrm/2sQH5Q0nxNuoZcxTGk3hD75Ntf6eqgclUQXJDEGbfoo3q7kYIQPXEIy\n" + - "+AuiMTd80ZRHuPBp8ci/wkh6N7B9mE/rjzJz77QgJluykoXRx9SiDyE4Yn9sRbBH\n" + - "jNm/KBv8wMV6hzJZYaALyDpGVNuAx9cHE91LaSvamPiccJn4wb9zDtyFduS3yYbz\n" + - "FREt960j420TeHjeWFkuXXVQMnPeRAWugclhJKzLz1U1gm5PWGxThMgVIy0v8v63\n" + - "3qFT09I4avi0AzBaRtINCaS39Mo2AoX1jZNjFDNLzRO1fSSJpzJmWyXJ2jRI7MwF\n" + - "AgMBAAGjggKDMIICfzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH\n" + - "AwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUCuJDEKGIdbWqxyVFZmIZoyQZ4T4w\n" + - "HwYDVR0jBBgwFoAUJeIYDrJXkZQq5dRdhpCD3lOzuJIweAYIKwYBBQUHAQEEbDBq\n" + - "MDUGCCsGAQUFBzABhilodHRwOi8vb2NzcC5wa2kuZ29vZy9zL2d0czFkNC9rb2Zm\n" + - "cmFBODZBdzAxBggrBgEFBQcwAoYlaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMv\n" + - "Z3RzMWQ0LmRlcjAmBgNVHREEHzAdghtyZXZva2VkLmd0c3IxLmRlbW8ucGtpLmdv\n" + - "b2cwIQYDVR0gBBowGDAIBgZngQwBAgEwDAYKKwYBBAHWeQIFAzA8BgNVHR8ENTAz\n" + - "MDGgL6AthitodHRwOi8vY3Jscy5wa2kuZ29vZy9ndHMxZDQvODJFckFFQVVsR1ku\n" + - "Y3JsMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHYArfe++nz/EMiLnT2cHj4YarRn\n" + - "KV3PsQwkyoWGNOvcgooAAAGHJM+cawAABAMARzBFAiB568monxGD3NiHsqNmsy+t\n" + - "IL4kCc71UNCCJthgnlL7HgIhAKSYf7P7CFO2wWdAt8LBMrsLoip9lytrinj0JR8R\n" + - "CYK9AHcAtz77JN+cTbp18jnFulj0bF38Qs96nzXEnh0JgSXttJkAAAGHJM+cZAAA\n" + - "BAMASDBGAiEAj8nBf1ihput8Gb8qCqVgvqAxPv9t4xLVhWg3tqv8gGMCIQDPiNbu\n" + - "vsyOi9nE6pDm86nggExXRa13wwCtr2wjAn5IpDANBgkqhkiG9w0BAQsFAAOCAQEA\n" + - "ezldM/NCUH58eXPZnbPaMMKrT5oNBxv+hypDy96+PyAqKtbC2bK+7sobGMZkfpG5\n" + - "8dW0mFmfazzjgbZUj54ZVHG4KaHeit8Nq1s07wh2Jo1c2JQdKxEXAOItax/IOfEd\n" + - "tqSg8AwSmhogQeiA7EXRspw4dYXL5uP/8jPPqByMI3PRmm3y7wyQLKNlNAfSgn7m\n" + - "wkrZxMRAENML4JND5UKxg7zo9e/Wvf4UPtEVVZaEj6ZxOe4JljvErCtayaw03t5p\n" + - "I18IAhXRpqm8JG1UGWjn49O8vkjB0bf/7iVXXI4rg6gGVia+HFuxKVGk5OQzo4Qd\n" + - "wBl6yOc8tpUH3phFPYbiMg==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon Mar 27 13:43:25 PDT 2023", System.out); - } -} - -class GoogleGTSR2 { - - // Owner: CN=GTS CA 1D8, O=Google Trust Services LLC, C=US - // Issuer: CN=GTS Root R2, O=Google Trust Services LLC, C=US - // Serial number: 219c15ac025a1b0a5c1d9d501 - // Valid from: Tue Oct 04 17:00:42 PDT 2022 until: Wed Sep 29 17:00:42 PDT 2027 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIFjDCCA3SgAwIBAgINAhnBWsAlobClwdnVATANBgkqhkiG9w0BAQsFADBHMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\n" + - "MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMjIxMDA1MDAwMDQyWhcNMjcwOTMwMDAw\n" + - "MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\n" + - "Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFEODCCASIwDQYJKoZIhvcNAQEBBQAD\n" + - "ggEPADCCAQoCggEBAKgpBAgi9bhOp5nCIELI/W+1rMoxNH3isu2LuDI3pPEPYJ0o\n" + - "YDxXB1zKHvUqn1VWDlF+K4vLPzjTRv2MUw8fHH9IAd/Rx+mrUHUxffTPU5O41tPj\n" + - "OdzFRO+FOr5RqZfbtXWbEUNyv7wyyCYr9gaDvDeQgDnHTfHAafdoDracNLm2LS3r\n" + - "8iznvJltsboRm+fBwTH99nHciN/h/hHEWlRriUGZ+Cz+5YVB9Tm4gAOByyYYbAa4\n" + - "ES0PhzkIUHaq+56cTDVhK0DM5ZtnZJqV8amhBFssswPttAXT9pNCzoDLCtxeZ2Lw\n" + - "r7bcaGaDcuDmv4j8zAw3BOR73O0Xk1VcBYPBBUcCAwEAAaOCAXYwggFyMA4GA1Ud\n" + - "DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T\n" + - "AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUkPhQ+ueQJcnkJ30S3UdY53QPtmowHwYD\n" + - "VR0jBBgwFoAUu//KjiOfT5nK2+JopqUVJxce2Q4waAYIKwYBBQUHAQEEXDBaMCYG\n" + - "CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMjAwBggrBgEFBQcw\n" + - "AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjIuZGVyMDQGA1UdHwQt\n" + - "MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjIvZ3RzcjIuY3JsME0G\n" + - "A1UdIARGMEQwCAYGZ4EMAQIBMDgGCisGAQQB1nkCBQMwKjAoBggrBgEFBQcCARYc\n" + - "aHR0cHM6Ly9wa2kuZ29vZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAgEA\n" + - "q3rJUW9syti3qkV5WNXCpJj2WoCptfxOdIrojT4Q1CIGzruFu4GXB8pfkJu7iU8k\n" + - "Aklel6RCn7MG/aI12ndmvUsW86e6UJDWEMz1CsQPA92AOsktAVXiGVDx3RAiPfP2\n" + - "9W9yNwlImSVZhGNQISC0SueK7QOv+mHHWE/7G0G0/YqAxMbVZzyrPYHfPUh0SD1g\n" + - "k7qYjq9hGJB7w7cfepZ2iPdKzlj/4aFOe04gho1zHMLJYIs03nb6uWg0AwX55SSu\n" + - "KvehoYs1ItHdEV1J2XfATZpCn6jMTEB/JYERbXW0VWLUhdaZORtaayQoU5YXbgvg\n" + - "bsPgqdIsPaxs/Chrp6zIKvs503YYcvs0GQSUQ1MFAWc+Loc39669T7WnL8Uu2yCO\n" + - "RxjFp3+fhTVA5UYwL1vy4wPnNUoa4+CA6JypT6ODUWcXZa8pWOdyHpbg0IeL389D\n" + - "s67kirG8/eKQxFzckbhL5AD8BJS3wkF7O7A8Gd+2VvSWhmEQzzOBHcvT/lqrCSe0\n" + - "7R7CV/Pw4E9C2GBLGfw8opxGXrdfJRjU6nHf5c+tC4xIjH/i3PQjaIFLG3D60mav\n" + - "0nkS92iorZl2dCiHTKxaD/J4B6VV03lpEcUdVg4WeGAmTClsXUnMOjCnlVYMLg9v\n" + - "URq0LbylxbGBelBrCNyqBS5UO6+9F4/Yi4vzoIvvbJ0=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.gtsr2.demo.pki.goog - // Issuer: CN=GTS CA 1D8, O=Google Trust Services LLC, C=US - // Serial number: 428fe99edb0df46e1008e4452f6cbfd2 - // Valid from: Mon Mar 27 12:52:12 PDT 2023 until: Sun Jun 25 12:52:11 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFdDCCBFygAwIBAgIQQo/pntsN9G4QCORFL2y/0jANBgkqhkiG9w0BAQsFADBG\n" + - "MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\n" + - "QzETMBEGA1UEAxMKR1RTIENBIDFEODAeFw0yMzAzMjcxOTUyMTJaFw0yMzA2MjUx\n" + - "OTUyMTFaMCMxITAfBgNVBAMTGGdvb2QuZ3RzcjIuZGVtby5wa2kuZ29vZzCCASIw\n" + - "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMaC0h20vohsggOQ0XGL5ca3Gqyf\n" + - "2n44PhYBrhzPpbq9/Mk9BKYYFy9osH0HwTFkYRYnI5fDeK6s/7svufiEwH8LtXK7\n" + - "A3juxf3k65cJ8M5bbBwDDW7Prgp86ueUd6pzqv23rLPc9Kv6vvtNYzgaTd4COU38\n" + - "3zFnuudAh8gvEbIQD+Nqis+kc4kEO3JfZBlAF883YRQZRpm6c4bWxKm1Atco53/6\n" + - "fYOota/XUgdJ8zQWOH1f9iaKX3kiDn76djxT9v/8MrcK2gRkHJJDo72HtCPuhdt8\n" + - "UkVLX4C3KF6eSUrgZ1gxA92ikAWxI4tn5D70yEffH0A7by0/b/C6uPMvXCECAwEA\n" + - "AaOCAn8wggJ7MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAM\n" + - "BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTegr5Cc+1LmL/c1H3sXVKufKZE8DAfBgNV\n" + - "HSMEGDAWgBSQ+FD655AlyeQnfRLdR1jndA+2ajB4BggrBgEFBQcBAQRsMGowNQYI\n" + - "KwYBBQUHMAGGKWh0dHA6Ly9vY3NwLnBraS5nb29nL3MvZ3RzMWQ4L0FoZFdDWF9D\n" + - "QUJFMDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMx\n" + - "ZDguZGVyMCMGA1UdEQQcMBqCGGdvb2QuZ3RzcjIuZGVtby5wa2kuZ29vZzAhBgNV\n" + - "HSAEGjAYMAgGBmeBDAECATAMBgorBgEEAdZ5AgUDMDwGA1UdHwQ1MDMwMaAvoC2G\n" + - "K2h0dHA6Ly9jcmxzLnBraS5nb29nL2d0czFkOC8tME5ITHA5Y0w5US5jcmwwggEE\n" + - "BgorBgEEAdZ5AgQCBIH1BIHyAPAAdgB6MoxU2LcttiDqOOBSHumEFnAyE4VNO9Ir\n" + - "wTpXo1LrUgAAAYck2PpFAAAEAwBHMEUCIAznUI2WdAkwXBvnx0a8Io6hnZReoXsd\n" + - "Y+o+xpXqZsbbAiEAw/i7jWA43QWEMZz265nflCNxAS1W+s7nsZaKL512/S8AdgDo\n" + - "PtDaPvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAYck2PoBAAAEAwBHMEUC\n" + - "IHWqRE57W1pJJJAXrxFNMrjEO3f0YejAfi47mdyS1zJYAiEA4ye+achvGTYIMRnl\n" + - "jwBlTsYQQYt7KAVt2VAGMRB4H8kwDQYJKoZIhvcNAQELBQADggEBAGf9hz7NJRow\n" + - "veCSrfeVav2tDkx8s9VU7VD+lApip1mdqOGsqkCkeaA5hsGfhqleQFwsOAjduBFA\n" + - "nSV6KgiqFsgHSuS9zuSp2aVe8xhxq6mpr4LngkeUDc32mB9tW9AMaiYp8UeYyFGq\n" + - "hvjUb7/H2wFlT6qO+Qp/+hmfulKqNnrSzpZLIl+x2EBn3L6CFe5xaKzNaANgbShI\n" + - "cQsyKdaUrSAzNJZWnHwaAyQ1msqqXXoVzKmjAGMgZrXZNxv8Lh9V1v+F9WHDIjeQ\n" + - "TtahntIgq38eGtZAnyjdrUtfQwBlQI3zaE0n7n6Fq8ocglJE5woRlL/eTmSKiZr9\n" + - "rrEY0sJ0fCw=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.gtsr2.demo.pki.goog - // Issuer: CN=GTS CA 1D8, O=Google Trust Services LLC, C=US - // Serial number: df9af5c19e9dbdf6107cb03548ffbd06 - // Valid from: Mon Mar 27 12:45:09 PDT 2023 until: Sun Jun 25 12:45:08 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIFejCCBGKgAwIBAgIRAN+a9cGenb32EHywNUj/vQYwDQYJKoZIhvcNAQELBQAw\n" + - "RjELMAkGA1UEBhMCVVMxIjAgBgNVBAoTGUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBM\n" + - "TEMxEzARBgNVBAMTCkdUUyBDQSAxRDgwHhcNMjMwMzI3MTk0NTA5WhcNMjMwNjI1\n" + - "MTk0NTA4WjAmMSQwIgYDVQQDExtyZXZva2VkLmd0c3IyLmRlbW8ucGtpLmdvb2cw\n" + - "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFJUSh0aOOjj6BXJqBFDOD\n" + - "GFjnr1VKDfWYdGWfB3QNhcbjz7qJRLeZDSYQZ3H2D5pkOQhl6xYLOZ1L0v+0TWW9\n" + - "5lCXQ476jdZXzPlOC29gYFX4VzS9w92ochg0dUhHdzKcWsqBjqChZdudGydYfwNS\n" + - "edZIhd4AcamVsXbCqAhS01Evo2hiBRlmMgryR9Ok2xRqbJiyvd8awhBIB4L0vMN+\n" + - "CgMpWMgaV1nn+LjEa3bHisyNVsRLdDZXY6Bgq3hUQ9jQWJdK/vGxHqunqC5ByrqG\n" + - "iN+4/+kK/PS8okkpAEAOXFoohogb6BQASMRgO/l50Mz8B24NGgWVLlWdaNysgU8f\n" + - "AgMBAAGjggKBMIICfTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH\n" + - "AwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUh/wMqf9pabUzGDoQvsyHVaT1rjAw\n" + - "HwYDVR0jBBgwFoAUkPhQ+ueQJcnkJ30S3UdY53QPtmoweAYIKwYBBQUHAQEEbDBq\n" + - "MDUGCCsGAQUFBzABhilodHRwOi8vb2NzcC5wa2kuZ29vZy9zL2d0czFkOC9CdWF6\n" + - "OFdQMnoybzAxBggrBgEFBQcwAoYlaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMv\n" + - "Z3RzMWQ4LmRlcjAmBgNVHREEHzAdghtyZXZva2VkLmd0c3IyLmRlbW8ucGtpLmdv\n" + - "b2cwIQYDVR0gBBowGDAIBgZngQwBAgEwDAYKKwYBBAHWeQIFAzA8BgNVHR8ENTAz\n" + - "MDGgL6AthitodHRwOi8vY3Jscy5wa2kuZ29vZy9ndHMxZDgvLTBOSExwOWNMOVEu\n" + - "Y3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYAejKMVNi3LbYg6jjgUh7phBZw\n" + - "MhOFTTvSK8E6V6NS61IAAAGHJNGpywAABAMARzBFAiEApXndD34BJ3oOCLvGoa5f\n" + - "Xu0P6t4yf1pdCQONuLTSrX4CIDMp1N5/VKjClXqE/t2xux3mvJH2ceVECID4B69v\n" + - "WfOhAHUA6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4AAAGHJNGphwAA\n" + - "BAMARjBEAiBa5aSnTCc2ceQj/asKFYRRGbwzXTnaDbvNMMeB4ogEXAIgZykyJVPh\n" + - "4Sfkroi8tvV6dwxexp0dT2EXHAmr+/GzZU0wDQYJKoZIhvcNAQELBQADggEBAHVn\n" + - "uWbk/OaljXKeyhlDCgdvnzJGCFQXwGyIJzNDkCs8k3iA1iwJKArvpkczxnCBxCPE\n" + - "imW2MHWCayT9JXKuO4ppU0oTh6GYvRV6DV1OkuWXsna7+dGf3+tkm9k0wauI6J8X\n" + - "H1T8Dq3W0+S+8UNSftduYSR1wTcN15OxIzlZ/FrV3LLRDxH2RKSsXfXBLgP1befh\n" + - "m+8SPQTpZ5NdMl7my0gmVgNF5ZIbFiHYzJkF2vS4iXJCI6fTWyoA1u/7jQyHdLOy\n" + - "pY0s6gKWEwwtpYC1lWI6ek/wLfuNrJbiRRiRs8e3HHQymn8K3T1PM+7n8huDy95b\n" + - "f1EgLMjvEtx6xpIqrqg=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon Mar 27 13:45:40 PDT 2023", System.out); - } -} - -class GoogleGTSR3 { - - // Owner: CN=GTS CA 2D3, O=Google Trust Services LLC, C=US - // Issuer: CN=GTS Root R3, O=Google Trust Services LLC, C=US - // Serial number: 21668d8d65bc4320e5b8e5e76 - // Valid from: Tue Oct 04 17:00:42 PDT 2022 until: Wed Sep 29 17:00:42 PDT 2027 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIDIDCCAqagAwIBAgINAhZo2NZbxDIOW45edjAKBggqhkjOPQQDAzBHMQswCQYD\n" + - "VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\n" + - "A1UEAxMLR1RTIFJvb3QgUjMwHhcNMjIxMDA1MDAwMDQyWhcNMjcwOTMwMDAwMDQy\n" + - "WjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\n" + - "IExMQzETMBEGA1UEAxMKR1RTIENBIDJEMzBZMBMGByqGSM49AgEGCCqGSM49AwEH\n" + - "A0IABGQQXn8LoR0OtyBn+KkEav3utA7WFBgWEb/8bXVlW6xJLTZJIC04lsNmNKWJ\n" + - "P/fwHYfrZcx1o4vvOUTO9OD/7pijggF2MIIBcjAOBgNVHQ8BAf8EBAMCAYYwHQYD\n" + - "VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAw\n" + - "HQYDVR0OBBYEFL+pU78badiFKTSaaUPL1nrUmf9tMB8GA1UdIwQYMBaAFMHxJrqg\n" + - "La6Fgc/T8SoSvbgKZ/28MGgGCCsGAQUFBwEBBFwwWjAmBggrBgEFBQcwAYYaaHR0\n" + - "cDovL29jc3AucGtpLmdvb2cvZ3RzcjMwMAYIKwYBBQUHMAKGJGh0dHA6Ly9wa2ku\n" + - "Z29vZy9yZXBvL2NlcnRzL2d0c3IzLmRlcjA0BgNVHR8ELTArMCmgJ6AlhiNodHRw\n" + - "Oi8vY3JsLnBraS5nb29nL2d0c3IzL2d0c3IzLmNybDBNBgNVHSAERjBEMAgGBmeB\n" + - "DAECATA4BgorBgEEAdZ5AgUDMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vcGtpLmdv\n" + - "b2cvcmVwb3NpdG9yeS8wCgYIKoZIzj0EAwMDaAAwZQIxAO3wG4U11INX3hl2UyCn\n" + - "0A/upBaO+BBzX1OiQx7UfmMXc65kqkdIcNzZc6G6EWnNVAIwBG0LuIKWXfYc+Wbk\n" + - "STfMvwatUvd6QjdIKsYF0e8Hiaav+hLI0DzOuJcDPFtfYIyY\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.gtsr3.demo.pki.goog - // Issuer: CN=GTS CA 2D3, O=Google Trust Services LLC, C=US - // Serial number: 7d08ad6716e51d1210bfc149e3d0af19 - // Valid from: Mon Mar 27 12:37:41 PDT 2023 until: Sun Jun 25 12:37:40 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIEszCCBFmgAwIBAgIQfQitZxblHRIQv8FJ49CvGTAKBggqhkjOPQQDAjBGMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzET\n" + - "MBEGA1UEAxMKR1RTIENBIDJEMzAeFw0yMzAzMjcxOTM3NDFaFw0yMzA2MjUxOTM3\n" + - "NDBaMCMxITAfBgNVBAMTGGdvb2QuZ3RzcjMuZGVtby5wa2kuZ29vZzCCASIwDQYJ\n" + - "KoZIhvcNAQEBBQADggEPADCCAQoCggEBAL7R40feuILVPC65FhoVh3kZ8mJuEKpJ\n" + - "SiSB9gbKRkaKBr4kHOm7+sa0RkAm3Zgbomd2JGiJbYYcQ4lY8MMlXruFLLY+0AMf\n" + - "Pf5mQbn6i+oSyfaNwV0Hk1q1MhZL5WSKLywXS0NVw50JGQw/SiIRhmR22DdOtxuh\n" + - "VC7ZOebYTbHzTBSYTxvoyJZ0bGUQMWQ0rI2lzOp+2kqSTDMmRejXUNm14ZrsdXUb\n" + - "F8nOunZpT5ppESFvsK7TFrWJlAFHNVxJjPkNaRyfIaR7G+hORoV5tHGaNeTzmFkO\n" + - "3ySGcRlvL41IWqBN4LwLiS6QN+Je7nIBDojEPTBVhPCzP++1uLKEKusCAwEAAaOC\n" + - "An8wggJ7MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNV\n" + - "HRMBAf8EAjAAMB0GA1UdDgQWBBRRhq17jer1cVfi0eFV+LIwk+Lk8jAfBgNVHSME\n" + - "GDAWgBS/qVO/G2nYhSk0mmlDy9Z61Jn/bTB4BggrBgEFBQcBAQRsMGowNQYIKwYB\n" + - "BQUHMAGGKWh0dHA6Ly9vY3NwLnBraS5nb29nL3MvZ3RzMmQzL09KOENlY2cwdWNV\n" + - "MDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMyZDMu\n" + - "ZGVyMCMGA1UdEQQcMBqCGGdvb2QuZ3RzcjMuZGVtby5wa2kuZ29vZzAhBgNVHSAE\n" + - "GjAYMAgGBmeBDAECATAMBgorBgEEAdZ5AgUDMDwGA1UdHwQ1MDMwMaAvoC2GK2h0\n" + - "dHA6Ly9jcmxzLnBraS5nb29nL2d0czJkMy9WREItNVdJSTVRSS5jcmwwggEEBgor\n" + - "BgEEAdZ5AgQCBIH1BIHyAPAAdgDoPtDaPvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9\n" + - "bQa9bgAAAYckzOfmAAAEAwBHMEUCIF0wxIlFnHLMan20Gtbnia+mzuA1Re0dhoIS\n" + - "wOAO7aC4AiEA7cYfSflOAA0DLxHsHAXpVs2LuLYlq34bSxbyUa85UyYAdgCzc3cH\n" + - "4YRQ+GOG1gWp3BEJSnktsWcMC4fc8AMOeTalmgAAAYckzOf5AAAEAwBHMEUCICza\n" + - "2nef9GWr9tF/ZXxhMYP15JQsdWPWmpQkdS/xUBWyAiEAs9AaeMarT7EaBVoSatAT\n" + - "Poj6cOhdvF/uDOHigyQdVd8wCgYIKoZIzj0EAwIDSAAwRQIhALv6jaEFgAIe3NbX\n" + - "87YEjhMMymK7wl435DQD9syoOEx2AiBbcYXr6nLNWA1pPoRiA1WvHgTVJFWftpYt\n" + - "e8CkUXnIxA==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.gtsr3.demo.pki.goog - // Issuer: CN=GTS CA 2D3, O=Google Trust Services LLC, C=US - // Serial number: 7ffa6a827df64c6010ebc47b5ca3eda7 - // Valid from: Mon Mar 27 12:45:58 PDT 2023 until: Sun Jun 25 12:45:57 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIEuTCCBF+gAwIBAgIQf/pqgn32TGAQ68R7XKPtpzAKBggqhkjOPQQDAjBGMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzET\n" + - "MBEGA1UEAxMKR1RTIENBIDJEMzAeFw0yMzAzMjcxOTQ1NThaFw0yMzA2MjUxOTQ1\n" + - "NTdaMCYxJDAiBgNVBAMTG3Jldm9rZWQuZ3RzcjMuZGVtby5wa2kuZ29vZzCCASIw\n" + - "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKpn78KglifqiS3f5hPLH64og4aH\n" + - "7a1tDBza2ebTLYB74i1u65EIENCyzvz6OYvh8kKzhqZMPFbORd8OCESzebjv/Dc2\n" + - "BJJV498N3BfSZYWN+baVxKuOZ4HWXV5NyP85rEvbcaAWcmqvh++G88FOCTQvYd4D\n" + - "/RKgAMptDjM+4X6V2NIRXcmOZJWZ2iItao76FARvbKH0D2UJLG4ENdOznRonnItP\n" + - "74UEVfNCb/i7I+NMJYTuDA4/rr+AS6pttvsVM9pqWkIJqOloEVNcCyyr1buflfJO\n" + - "j4A8Nz9fTUffpfApQnPi394iUcdCVyCrcjB2ta2eMR/3AyhiSXOmxcGjUcECAwEA\n" + - "AaOCAoIwggJ+MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAM\n" + - "BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSg57WFIkW4b1eTcWX+qZsN+JEewTAfBgNV\n" + - "HSMEGDAWgBS/qVO/G2nYhSk0mmlDy9Z61Jn/bTB4BggrBgEFBQcBAQRsMGowNQYI\n" + - "KwYBBQUHMAGGKWh0dHA6Ly9vY3NwLnBraS5nb29nL3MvZ3RzMmQzL1pEZWExWTdT\n" + - "SlBZMDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMy\n" + - "ZDMuZGVyMCYGA1UdEQQfMB2CG3Jldm9rZWQuZ3RzcjMuZGVtby5wa2kuZ29vZzAh\n" + - "BgNVHSAEGjAYMAgGBmeBDAECATAMBgorBgEEAdZ5AgUDMDwGA1UdHwQ1MDMwMaAv\n" + - "oC2GK2h0dHA6Ly9jcmxzLnBraS5nb29nL2d0czJkMy9WREItNVdJSTVRSS5jcmww\n" + - "ggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdQDoPtDaPvUGNTLnVyi8iWvJA9PL0RFr\n" + - "7Otp4Xd9bQa9bgAAAYck00MJAAAEAwBGMEQCIALwbMReWy/zrvUwV1G5XOxN8koN\n" + - "VJ1pp7s1d7ClE9ebAiBYWwJeccnfHLIh9AJTdeuN+R/pDzEudVBSC2rIdo3HhgB3\n" + - "ALc++yTfnE26dfI5xbpY9Gxd/ELPep81xJ4dCYEl7bSZAAABhyTTQzMAAAQDAEgw\n" + - "RgIhAOEO0oyiRgMNDdWvRTobr7sex2SUFsjpKmwenYAULrRiAiEA6uKFK1sbnJ1J\n" + - "lW8Tw2G4jGpEFIc4C9duRbU6DIbGnckwCgYIKoZIzj0EAwIDSAAwRQIgN3byD4lu\n" + - "a8A0hzUR1OnPoXSyfus6HOhmBozH6coY9MICIQDsT5jj5GKVtxtlcki5iE08K70Z\n" + - "gt/tkcE1Fkk4RsZORA==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon Mar 27 13:47:24 PDT 2023", System.out); - } -} - -class GoogleGTSR4 { - - // Owner: CN=GTS CA 2P2, O=Google Trust Services LLC, C=US - // Issuer: CN=GTS Root R4, O=Google Trust Services LLC, C=US - // Serial number: 2166825e1700440612491f540 - // Valid from: Tue Oct 04 17:00:42 PDT 2022 until: Wed Sep 29 17:00:42 PDT 2027 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIDITCCAqagAwIBAgINAhZoJeFwBEBhJJH1QDAKBggqhkjOPQQDAzBHMQswCQYD\n" + - "VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\n" + - "A1UEAxMLR1RTIFJvb3QgUjQwHhcNMjIxMDA1MDAwMDQyWhcNMjcwOTMwMDAwMDQy\n" + - "WjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\n" + - "IExMQzETMBEGA1UEAxMKR1RTIENBIDJQMjBZMBMGByqGSM49AgEGCCqGSM49AwEH\n" + - "A0IABKdQkzjAHqOUsb/TkH7cz5lRtD374tNZ8rYrCUb1mxypE+VmCb1Jgzq+93tR\n" + - "dE78GRzPI4+q6raha1TEyWgoniOjggF2MIIBcjAOBgNVHQ8BAf8EBAMCAYYwHQYD\n" + - "VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAw\n" + - "HQYDVR0OBBYEFIcjqVBIDgeJVApxMPYz0gpH9p2sMB8GA1UdIwQYMBaAFIBM1ut0\n" + - "/0k2o9XY/LU+xWrwlB2MMGgGCCsGAQUFBwEBBFwwWjAmBggrBgEFBQcwAYYaaHR0\n" + - "cDovL29jc3AucGtpLmdvb2cvZ3RzcjQwMAYIKwYBBQUHMAKGJGh0dHA6Ly9wa2ku\n" + - "Z29vZy9yZXBvL2NlcnRzL2d0c3I0LmRlcjA0BgNVHR8ELTArMCmgJ6AlhiNodHRw\n" + - "Oi8vY3JsLnBraS5nb29nL2d0c3I0L2d0c3I0LmNybDBNBgNVHSAERjBEMAgGBmeB\n" + - "DAECATA4BgorBgEEAdZ5AgUDMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vcGtpLmdv\n" + - "b2cvcmVwb3NpdG9yeS8wCgYIKoZIzj0EAwMDaQAwZgIxAMnbIiQb5fsdexUuVGoB\n" + - "MVwsDPGd7VC13Y0OBezt7FqFHDwqm8nnVdV/FkNyXNv9/AIxAN51NGqMcbexMOYK\n" + - "pLC0zXfjNwvqBsZhmzCCQIM6MVyBID0rjjxPu7laIaHqAu6T5Q==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.gtsr4.demo.pki.goog - // Issuer: CN=GTS CA 2P2, O=Google Trust Services LLC, C=US - // Serial number: 743c4f78750e30f0d407a19254ba96a - // Valid from: Mon Mar 27 12:40:42 PDT 2023 until: Sun Jun 25 12:40:41 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIEsTCCBFegAwIBAgIQB0PE94dQ4w8NQHoZJUupajAKBggqhkjOPQQDAjBGMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzET\n" + - "MBEGA1UEAxMKR1RTIENBIDJQMjAeFw0yMzAzMjcxOTQwNDJaFw0yMzA2MjUxOTQw\n" + - "NDFaMCMxITAfBgNVBAMTGGdvb2QuZ3RzcjQuZGVtby5wa2kuZ29vZzCCASIwDQYJ\n" + - "KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdkWBg3i5CxzH1dvlBoWHtIUyk78OAA\n" + - "bZdq7pKWB8i8C9Rf089uQ+7jQWOmqCNxU+OXdjumPfk/4MQvvtkmaqKi7HCN1bvQ\n" + - "0CrW7Zhi5jx11QuzEEZVdvXcchzmodp9GSl9t6zK/ItNiIYVisH9dqRWrZ/KZnO+\n" + - "y13dlr5UXAXVvNKx1L4TjhGlam7IEJdrAjkLJk4wXAFhv9HaPNJnjj0306xNm2h+\n" + - "VzldpMPlaXGN9JcGQdMVFpa9f0AI/r7SF7I2EDXaIKFToJ4jQurEGc3oxayiv9wB\n" + - "QapXqSTbPztb5SPGdX1yawDeigNHf10tDqFzCpfI/AwLxagpA2YyyXMCAwEAAaOC\n" + - "An0wggJ5MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNV\n" + - "HRMBAf8EAjAAMB0GA1UdDgQWBBTZs4UFHCFLlXnJswubCMxEhtgPmjAfBgNVHSME\n" + - "GDAWgBSHI6lQSA4HiVQKcTD2M9IKR/adrDB4BggrBgEFBQcBAQRsMGowNQYIKwYB\n" + - "BQUHMAGGKWh0dHA6Ly9vY3NwLnBraS5nb29nL3MvZ3RzMnAyL3dKWTY1eFNLQUNB\n" + - "MDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMycDIu\n" + - "ZGVyMCMGA1UdEQQcMBqCGGdvb2QuZ3RzcjQuZGVtby5wa2kuZ29vZzAhBgNVHSAE\n" + - "GjAYMAgGBmeBDAECATAMBgorBgEEAdZ5AgUDMDwGA1UdHwQ1MDMwMaAvoC2GK2h0\n" + - "dHA6Ly9jcmxzLnBraS5nb29nL2d0czJwMi94NWswT2ZlZ0o4OC5jcmwwggECBgor\n" + - "BgEEAdZ5AgQCBIHzBIHwAO4AdQDoPtDaPvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9\n" + - "bQa9bgAAAYckzdBSAAAEAwBGMEQCICpm7XEQds5Pzk59Qhhlx3PjipAEVzxVJB3H\n" + - "UmmGlHYKAiBG39UauHNNQDMYK2PEnILbFI0AvVWpCBUck4CHbs+9xAB1AHoyjFTY\n" + - "ty22IOo44FIe6YQWcDIThU070ivBOlejUutSAAABhyTN0JoAAAQDAEYwRAIgekoP\n" + - "yJFspEfqvzW/pzVtRn8oz1L/PBzw2NYRPFdDkRUCIG1uIaGUA7uqiILD6vvp/1VD\n" + - "XriEIH8/qz/3qWqxsZanMAoGCCqGSM49BAMCA0gAMEUCIQCnpyh5H9Hn+f8nOFZp\n" + - "wz7p+x5pmMVvPzah1g+EmoFO/wIgStidgVhudT/vpM2OH/oN30Na+EJJDqWxousN\n" + - "6t9L8FQ=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.gtsr4.demo.pki.goog - // Issuer: CN=GTS CA 2P2, O=Google Trust Services LLC, C=US - // Serial number: 6b2d650d4bc3bd3f11a595bf05187915 - // Valid from: Mon Mar 27 12:47:43 PDT 2023 until: Sun Jun 25 12:47:42 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIEuDCCBF6gAwIBAgIQay1lDUvDvT8RpZW/BRh5FTAKBggqhkjOPQQDAjBGMQsw\n" + - "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzET\n" + - "MBEGA1UEAxMKR1RTIENBIDJQMjAeFw0yMzAzMjcxOTQ3NDNaFw0yMzA2MjUxOTQ3\n" + - "NDJaMCYxJDAiBgNVBAMTG3Jldm9rZWQuZ3RzcjQuZGVtby5wa2kuZ29vZzCCASIw\n" + - "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOEKoC1Zv/m2G8DrGkOgLq5TPSeC\n" + - "X3cClcI6s4JS5Cld2DKX7m4P8rXAxJyVHvlmkxZQoD6Y7JxsavlJ/Yw0qdqkNLTv\n" + - "kviEiLNYEn8Qu0SoRLNanzoFUINZkAZ4/0Lfvsrl9tTigLsCJ4jQauemGmGcmKUy\n" + - "qsKisfrMC0ZG9EP9WRjc9WF13Jqe55+gZ7LqaAAoPVR/7J6T1VAKteaYaXrORtVF\n" + - "uMeinE4c9YuxRCLa+3X1qqc3HAsvZEBOdb35fC0cN/ILktCQpq1Fj+QD4jfR6bVQ\n" + - "E8eA6Jy+5qHSg2VjAm6wNLd5QkfE7D8uC9sYs638r48ahcXhy3zwpzGhuH0CAwEA\n" + - "AaOCAoEwggJ9MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAM\n" + - "BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQl5Uh4jTR3l8PkcLdBwtwQXkUzBjAfBgNV\n" + - "HSMEGDAWgBSHI6lQSA4HiVQKcTD2M9IKR/adrDB4BggrBgEFBQcBAQRsMGowNQYI\n" + - "KwYBBQUHMAGGKWh0dHA6Ly9vY3NwLnBraS5nb29nL3MvZ3RzMnAyL3h5WmtBTEE3\n" + - "aGY0MDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMy\n" + - "cDIuZGVyMCYGA1UdEQQfMB2CG3Jldm9rZWQuZ3RzcjQuZGVtby5wa2kuZ29vZzAh\n" + - "BgNVHSAEGjAYMAgGBmeBDAECATAMBgorBgEEAdZ5AgUDMDwGA1UdHwQ1MDMwMaAv\n" + - "oC2GK2h0dHA6Ly9jcmxzLnBraS5nb29nL2d0czJwMi9sU1htaTNxZWRoYy5jcmww\n" + - "ggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdgCt9776fP8QyIudPZwePhhqtGcpXc+x\n" + - "DCTKhYY069yCigAAAYck1BYGAAAEAwBHMEUCIGM5ykDTU3mqgLIk+fPmVn6JGUXB\n" + - "W4xouGUA1iiNs7G0AiEAtuWnV/J5llcxB7ZTwkCb6cviyv4Z6O396ZGW8GsrqAQA\n" + - "dQC3Pvsk35xNunXyOcW6WPRsXfxCz3qfNcSeHQmBJe20mQAAAYck1BYIAAAEAwBG\n" + - "MEQCIHcK1H025GIv8klzQGSZAL9NnuH5EzeGra0jRRg5RM4UAiAQaJyJDBkJRL/C\n" + - "F9WCg9Lmp8bdsXkG5WPreI24ansAPTAKBggqhkjOPQQDAgNIADBFAiBehPLU7raP\n" + - "509khaP9yiKiL3mbygtfQo4MDpBnd2RI6wIhAOdlQythGgU+nOENodsB+wUOQXOb\n" + - "akcBOxrDWfyhxmpk\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon Mar 27 13:48:18 PDT 2023", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2017, 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. - */ - - /* - * @test - * @bug 8189131 - * @summary Interoperability tests with Let's Encrypt CA - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath LetsEncryptCA OCSP - * @run main/othervm -Djava.security.debug=certpath LetsEncryptCA CRL - */ - - /* - * Obtain TLS test artifacts for Let's Encrypt CA from: - * - * Valid TLS Certificates: - * https://valid-isrgrootx1.letsencrypt.org/ - * - * Revoked TLS Certificates: - * https://revoked-isrgrootx1.letsencrypt.org/ - * - * Test artifacts don't have CRLs listed and intermediate cert doesn't have OCSP. - */ -public class LetsEncryptCA { - - // Owner: CN=R3, O=Let's Encrypt, C=US - // Issuer: CN=ISRG Root X1, O=Internet Security Research Group, C=US - // Serial number: 912b084acf0c18a753f6d62e25a75f5a - // Valid from: Thu Sep 03 17:00:00 PDT 2020 until: Mon Sep 15 09:00:00 PDT 2025 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw\n" + - "TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n" + - "cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw\n" + - "WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg\n" + - "RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" + - "AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP\n" + - "R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx\n" + - "sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm\n" + - "NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg\n" + - "Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG\n" + - "/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC\n" + - "AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB\n" + - "Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA\n" + - "FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw\n" + - "AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw\n" + - "Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB\n" + - "gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W\n" + - "PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl\n" + - "ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz\n" + - "CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm\n" + - "lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4\n" + - "avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2\n" + - "yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O\n" + - "yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids\n" + - "hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+\n" + - "HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv\n" + - "MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX\n" + - "nLRbwHOoq7hHwg==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=valid-isrgrootx1.letsencrypt.org - // Issuer: CN=R3, O=Let's Encrypt, C=US - // Serial number: 46326744d1c2f3feeca7148ed59353144a6 - // Valid from: Wed Jun 02 08:00:18 PDT 2021 until: Tue Aug 31 08:00:18 PDT 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFSDCCBDCgAwIBAgISBGMmdE0cLz/uynFI7Vk1MUSmMA0GCSqGSIb3DQEBCwUA\n" + - "MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\n" + - "EwJSMzAeFw0yMTA2MDIxNTAwMThaFw0yMTA4MzExNTAwMThaMCsxKTAnBgNVBAMT\n" + - "IHZhbGlkLWlzcmdyb290eDEubGV0c2VuY3J5cHQub3JnMIIBIjANBgkqhkiG9w0B\n" + - "AQEFAAOCAQ8AMIIBCgKCAQEAmdx7jlaUZ0MgEvqzYWXItAFxVAOmR3KF+79vU195\n" + - "O5X54Go1+GU+eyFAeTqr6W1gC/MIrSA9LO4neJUx5AWCYaLq7IE7/YnmXTT6BB0x\n" + - "WFN3V1OJg9bAqpcEclQp6fbQS6DjdQvUUaEvVIwPzaen6Hmtw6LuHOYOdLk4fUSm\n" + - "zadWiyNlMm0/ts+MLHY5iQd9ypGhJED7KBDQ4d4wvyMYo/MYKOUQ+dTXcIegh7p4\n" + - "0OVtbrkdCuGJL+cEw1IUtSNQD+MnvUIu1je7Yb6iZ6Qd3iopNLykHYZb8YemakGX\n" + - "SDdC54yi35NU+Y+l23vycbVmRd8vK1sizhjRSE+ufmEqXQIDAQABo4ICXTCCAlkw\n" + - "DgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAM\n" + - "BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBR300bKVFG2auzS0mO4+E57SN6QLzAfBgNV\n" + - "HSMEGDAWgBQULrMXt1hWy65QCUDmH6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYI\n" + - "KwYBBQUHMAGGFWh0dHA6Ly9yMy5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0\n" + - "cDovL3IzLmkubGVuY3Iub3JnLzArBgNVHREEJDAigiB2YWxpZC1pc3Jncm9vdHgx\n" + - "LmxldHNlbmNyeXB0Lm9yZzBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLf\n" + - "EwEBATAoMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCC\n" + - "AQYGCisGAQQB1nkCBAIEgfcEgfQA8gB3APZclC/RdzAiFFQYCDCUVo7jTRMZM7/f\n" + - "DC8gC8xO8WTjAAABec10PpUAAAQDAEgwRgIhAPDWvnP5mA0RhPa9oiTlE21Ppcez\n" + - "eF1+wU0MeoQcjq/7AiEAsox8kMGpWXq0ZVPweTpw1So/sNOZTsSPyBUdbLwjf+MA\n" + - "dwBvU3asMfAxGdiZAKRRFf93FRwR2QLBACkGjbIImjfZEwAAAXnNdD7rAAAEAwBI\n" + - "MEYCIQCYBSmmb5P+DZGANyYTPHlEbmqOBkEOblkEHq5Lf+wtkQIhAO2HhwOm3wns\n" + - "ZTsXjUCcfQA0lKBI2TKkg9tJKFs3uuKDMA0GCSqGSIb3DQEBCwUAA4IBAQBJJ47x\n" + - "ZhKN3QRBYVROpoYDSh0a/JW7zPGRCxK5fnDY9UT8m4gEh3yhDTkycX+vo8TReK6W\n" + - "fEYareTSTq71MYgtKDYEARm10DuL7Vdig9Tf5DpjXLHaba+wqPz24lwhiJgoKRRr\n" + - "8by3wXPFCGSuQyDo1ZUNrAJVYKO4hPMob1ZE8z9IYW63GvzBjEla/HxoVa9iTkv+\n" + - "31rsKzpSbMJpnQ7WcgkUPdpoDo4JElGCyf7VZHNicumipAiCmKu0Q6TRCPOXxlKE\n" + - "/BIyDey3rXVw3wzOlxmVF6t/V3vGtbgVvN/feUe/ytyv4vLfRR4udi2XxWt3x1la\n" + - "7R3zuWdRQhh21p1H\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked-isrgrootx1.letsencrypt.org - // Issuer: CN=R3, O=Let's Encrypt, C=US - // Serial number: 4f1333011635d76d6356c5f1fb8a7273617 - // Valid from: Fri Jun 25 08:18:10 PDT 2021 until: Thu Sep 23 08:18:09 PDT 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIFSTCCBDGgAwIBAgISBPEzMBFjXXbWNWxfH7inJzYXMA0GCSqGSIb3DQEBCwUA\n" + - "MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\n" + - "EwJSMzAeFw0yMTA2MjUxNTE4MTBaFw0yMTA5MjMxNTE4MDlaMC0xKzApBgNVBAMT\n" + - "InJldm9rZWQtaXNyZ3Jvb3R4MS5sZXRzZW5jcnlwdC5vcmcwggEiMA0GCSqGSIb3\n" + - "DQEBAQUAA4IBDwAwggEKAoIBAQCkCp4fq7FnN5lfAWX0vhCcyC5WO9TuU6ckuYYj\n" + - "8/wQ8GQ/FIl+vXCAmHIfIX14irQN8TISeVdMOP0C7sa73d3GSawX7qMaRhddXn7V\n" + - "EL+4CbHQ6qit5YkakwhHz9tKbYX16wPj+inn22kJVwi8iLbhYB9WWSvv7OyiNSHv\n" + - "nmlYUkMv8+9UhgPT4yCKF1OEI5ajUOuecjOKc+EzsT/JqPRErvBOIKn3PRn4h8UM\n" + - "0BJDrDtZMpkvD4/lyRs3g/BLsf3DQjlEgKit0hvc72yyhiDbKd41EmBoQC5rNF7o\n" + - "B0CnBXhDLHbC/YRunVrYGsF0h2J9hw4055BdaXbS2BJnPEFnAgMBAAGjggJcMIIC\n" + - "WDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" + - "MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFJBkf3Z/ICoCTUx3JCgrBeoMyedQMB8G\n" + - "A1UdIwQYMBaAFBQusxe3WFbLrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAh\n" + - "BggrBgEFBQcwAYYVaHR0cDovL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZo\n" + - "dHRwOi8vcjMuaS5sZW5jci5vcmcvMC0GA1UdEQQmMCSCInJldm9rZWQtaXNyZ3Jv\n" + - "b3R4MS5sZXRzZW5jcnlwdC5vcmcwTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYB\n" + - "BAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5v\n" + - "cmcwggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdQCUILwejtWNbIhzH4KLIiwN0dpN\n" + - "XmxPlD1h204vWE2iwgAAAXpD9t6nAAAEAwBGMEQCIHwF9NcPqsovYp56lhqFkWYj\n" + - "QCATATrLzzxgUoLDYRwgAiBBecqe5Ub32I+q9oqH1nbK/s8QadcafIL3bkrRVbFB\n" + - "TAB2AH0+8viP/4hVaCTCwMqeUol5K8UOeAl/LmqXaJl+IvDXAAABekP23sYAAAQD\n" + - "AEcwRQIgGli/1mmKKnZ0uxDIX7ySqAyD2C7FTf+y3py2S0Xcv4YCIQCZve3cqKZ2\n" + - "lrEyyaMeLZA+PIxUMniHx3gDkro0sKLzOzANBgkqhkiG9w0BAQsFAAOCAQEAle42\n" + - "p58OTusm7DAOcdK4ld+pJu2bz9F940Wrnql08rciRjGIVpp5PhMNFm9AOaptKPNY\n" + - "h62V2GEOVaLxmvr9/8EDFcCCPAGV1DNYrG9aTKaiXk7IzO4UxKbzox4iUcuop/zB\n" + - "uofxT8uBLmT4XYZrQXXKj1KdfJGzgeoXqBv5PPCiP3hmBQixoJnSKImnUIXWh4O8\n" + - "kBtmgII5ug0q+jI3LvpJuv7xQsaNYFBcmFiQQ7YRt4W99GMdbYGjhzT8iBDEH7nG\n" + - "MsqWuwB5TN5vIuw2aWxcfaqKayq7UPA4rJePWdD/5RzKlQKLQx0BA3AL+3Nnj1fT\n" + - "NEKwCWWylIND6z/9Xw==\n" + - "-----END CERTIFICATE-----"; - - public static void main(String[] args) throws Exception { - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - pathValidator.enableCRLCheck(); - - // Validate int, EE certs don't have CRLs - pathValidator.validate(new String[]{INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - return; - } - - // OCSP check by default - // intermediate cert R3 doesn't specify OCSP responder - ValidatePathWithParams pathValidator = new ValidatePathWithParams(new String[]{INT}); - pathValidator.enableOCSPCheck(); - - // Validate valid - pathValidator.validate(new String[]{VALID}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED}, - ValidatePathWithParams.Status.REVOKED, - "Fri Jun 25 09:18:12 PDT 2021", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/MicrosoftTLS.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,348 +0,0 @@ -/* - * 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 8304760 - * @summary Interoperability tests with Microsoft TLS root CAs - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath MicrosoftTLS OCSP - * @run main/othervm -Djava.security.debug=certpath MicrosoftTLS CRL - */ - -/* - * Microsoft ECC Root Certificate Authority 2017: - * Valid: http://acteccroot2017.pki.microsoft.com/ - * Revoked: http://rvkeccroot2017.pki.microsoft.com/ - * Expired: http://expeccroot2017.pki.microsoft.com/ - * - * Microsoft RSA Root Certificate Authority 2017: - * Valid: http://actrsaroot2017.pki.microsoft.com/ - * Revoked: http://rvkrsaroot2017.pki.microsoft.com/ - * Expired: http://exprsaroot2017.pki.microsoft.com/ - */ -public class MicrosoftTLS { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - new MicrosoftECCTLS().runTest(pathValidator); - new MicrosoftRSATLS().runTest(pathValidator); - } -} - -class MicrosoftECCTLS { - - // Owner: CN=Microsoft ECC TLS Issuing AOC CA 01, O=Microsoft Corporation, C=US - // Issuer: CN=Microsoft ECC Root Certificate Authority 2017, O=Microsoft - // Corporation, C=US - // Serial number: 33000000282bfd23e7d1add707000000000028 - // Valid from: Thu Jun 24 12:58:36 PDT 2021 until: Wed Jun 24 12:58:36 PDT 2026 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIESTCCA8+gAwIBAgITMwAAACgr/SPn0a3XBwAAAAAAKDAKBggqhkjOPQQDAzBl\n" + - "MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw\n" + - "NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5\n" + - "IDIwMTcwHhcNMjEwNjI0MTk1ODM2WhcNMjYwNjI0MTk1ODM2WjBbMQswCQYDVQQG\n" + - "EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSwwKgYDVQQDEyNN\n" + - "aWNyb3NvZnQgRUNDIFRMUyBJc3N1aW5nIEFPQyBDQSAwMTB2MBAGByqGSM49AgEG\n" + - "BSuBBAAiA2IABMBXcHExvrYrhw7v30oPR4aBaMne5o0FtTtbMV7iqVhTJDQSWDEJ\n" + - "hr528nyS6jcLLu9pLXQMJYxVd7bz4wWXgVtZnnbQ7trAAIPWVh5B6f5eJf5OQ7w7\n" + - "AwJgz3snP5Hx16OCAkkwggJFMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEE\n" + - "AwIBADAdBgNVHQ4EFgQUMVu5zlEbfNGqA8Dr7TZdwp3TieEwHQYDVR0lBBYwFAYI\n" + - "KwYBBQUHAwEGCCsGAQUFBwMCMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMBIG\n" + - "A1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUyMuZcnBSDPjmvrIEVykqz0IQ\n" + - "7TUwcAYDVR0fBGkwZzBloGOgYYZfaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br\n" + - "aW9wcy9jcmwvTWljcm9zb2Z0JTIwRUNDJTIwUm9vdCUyMENlcnRpZmljYXRlJTIw\n" + - "QXV0aG9yaXR5JTIwMjAxNy5jcmwwga4GCCsGAQUFBwEBBIGhMIGeMG0GCCsGAQUF\n" + - "BzAChmFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jv\n" + - "c29mdCUyMEVDQyUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIw\n" + - "MTcuY3J0MC0GCCsGAQUFBzABhiFodHRwOi8vb25lb2NzcC5taWNyb3NvZnQuY29t\n" + - "L29jc3AwcAYDVR0gBGkwZzAIBgZngQwBAgEwCAYGZ4EMAQICMFEGDCsGAQQBgjdM\n" + - "g30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp\n" + - "b3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wCgYIKoZIzj0EAwMDaAAwZQIxANmPydUj\n" + - "lgj/2K77UnMeMkSGIgXzOhcTsixzZL+NmTR1Bq2hSPeA6Y3mn3lMlwxZmAIwIio6\n" + - "KrgItH4YmLWKd8QClIrE9QjbDlR7oFqaU3J34bWbMlAEjRARdZhhQlNwdORe\n" + - "-----END CERTIFICATE-----"; - - // Owner: O=Microsoft Corporation, L=Redmond, ST=Washington, C=US - // Issuer: CN=Microsoft ECC TLS Issuing AOC CA 01, O=Microsoft Corporation, C=US - // Serial number: 3300000154e1c6007ee3d5c903000000000154 - // Valid from: Fri Oct 14 13:44:52 PDT 2022 until: Mon Oct 09 13:44:52 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIF3zCCBWSgAwIBAgITMwAAAVThxgB+49XJAwAAAAABVDAKBggqhkjOPQQDAzBb\n" + - "MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSww\n" + - "KgYDVQQDEyNNaWNyb3NvZnQgRUNDIFRMUyBJc3N1aW5nIEFPQyBDQSAwMTAeFw0y\n" + - "MjEwMTQyMDQ0NTJaFw0yMzEwMDkyMDQ0NTJaMFQxCzAJBgNVBAYTAlVTMRMwEQYD\n" + - "VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\n" + - "b3NvZnQgQ29ycG9yYXRpb24wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARk86yqvyiv\n" + - "jH2Frg2l6bmh1f0CqiKAEHdA2S2vTQhR4CtvFArkrPdqcKrhAAfQSgnC8KJQ08gl\n" + - "QvjK55202ib55YX3h+96IW6fQOkE18cvPwqkD3DVQuROouLaL1r70NWjggPvMIID\n" + - "6zCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYA6D7Q2j71BjUy51covIlryQPT\n" + - "y9ERa+zraeF3fW0GvW4AAAGD2EdUigAABAMARzBFAiEA6rbt+9QhpuqX36PnuckO\n" + - "fR0Wu/8z3Yry9fdFKvJDCEUCIGBz901b4ZGEjCaSJdlZVr29v2td4crPa9I6S97i\n" + - "nShAAHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAGD2EdU/wAA\n" + - "BAMARzBFAiBIvnSKGeCIWOlZowi7s7ZdwmyGhv2waJWSdewUSS6UOAIhALJhPQ19\n" + - "nmjjTwWB9sgCIF7RZbd2xwBd1hno06MQMSqTAHcAejKMVNi3LbYg6jjgUh7phBZw\n" + - "MhOFTTvSK8E6V6NS61IAAAGD2EdUxwAABAMASDBGAiEArrc6Fu74KTj/z4lGCK9A\n" + - "O6UkhLpKnXdxEHilY7ghcZICIQCUjkvK4wehX1qEonjQoBkBJxLCus6y8WbkoxCe\n" + - "jHu2HTAbBgkrBgEEAYI3FQoEDjAMMAoGCCsGAQUFBwMBMDwGCSsGAQQBgjcVBwQv\n" + - "MC0GJSsGAQQBgjcVCIe91xuB5+tGgoGdLo7QDIfw2h1dgbXdUIWf/XUCAWQCAR0w\n" + - "gaYGCCsGAQUFBwEBBIGZMIGWMGUGCCsGAQUFBzAChllodHRwOi8vd3d3Lm1pY3Jv\n" + - "c29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMEVDQyUyMFRMUyUyMElz\n" + - "c3VpbmclMjBBT0MlMjBDQSUyMDAxLmNydDAtBggrBgEFBQcwAYYhaHR0cDovL29u\n" + - "ZW9jc3AubWljcm9zb2Z0LmNvbS9vY3NwMB0GA1UdDgQWBBTVpTA+3jWCa1okX5Ri\n" + - "HnuY2/b+IzAOBgNVHQ8BAf8EBAMCB4AwKwYDVR0RBCQwIoIgYWN0ZWNjcm9vdDIw\n" + - "MTcucGtpLm1pY3Jvc29mdC5jb20waAYDVR0fBGEwXzBdoFugWYZXaHR0cDovL3d3\n" + - "dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwRUNDJTIwVExT\n" + - "JTIwSXNzdWluZyUyMEFPQyUyMENBJTIwMDEuY3JsMGYGA1UdIARfMF0wUQYMKwYB\n" + - "BAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNv\n" + - "bS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAIBgZngQwBAgIwHwYDVR0jBBgw\n" + - "FoAUMVu5zlEbfNGqA8Dr7TZdwp3TieEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCgYI\n" + - "KoZIzj0EAwMDaQAwZgIxAOKV8s3SpXVd6zho8zQa4uGXkxPVocYo410FdTwu0lw7\n" + - "G/MQPhLmj4DNsQJ/nYzDcwIxAMw7iZExsY9Is66/EaAty4rA+yuliwCag88VnDRH\n" + - "9cjiongZgpddIYS8xf76B2pi/Q==\n" + - "-----END CERTIFICATE-----"; - - // Owner: O=Microsoft Corporation, L=Redmond, ST=Washington, C=US - // Issuer: CN=Microsoft ECC TLS Issuing AOC CA 01, O=Microsoft Corporation, C=US - // Serial number: 3300000155ea28117be8708034000000000155 - // Valid from: Fri Oct 14 13:50:39 PDT 2022 until: Mon Oct 09 13:50:39 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIF3TCCBWOgAwIBAgITMwAAAVXqKBF76HCANAAAAAABVTAKBggqhkjOPQQDAzBb\n" + - "MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSww\n" + - "KgYDVQQDEyNNaWNyb3NvZnQgRUNDIFRMUyBJc3N1aW5nIEFPQyBDQSAwMTAeFw0y\n" + - "MjEwMTQyMDUwMzlaFw0yMzEwMDkyMDUwMzlaMFQxCzAJBgNVBAYTAlVTMRMwEQYD\n" + - "VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\n" + - "b3NvZnQgQ29ycG9yYXRpb24wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARbimHzMojc\n" + - "ilBoJCu+adc99oS855DwGTmkKofXfEf6Ej6G9v6Zg1Y2a1wqs5Wd3IcqQONeqKK8\n" + - "EGxUL7DBpf1dBDsRpWSfenYIRtAzs/JznW0dfGPgnY0kGi4g52JegCOjggPuMIID\n" + - "6jCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHUArfe++nz/EMiLnT2cHj4YarRn\n" + - "KV3PsQwkyoWGNOvcgooAAAGD2EyY+gAABAMARjBEAiBnysZazdmXKeL4CnYkJxI2\n" + - "g5juWT5jQfBi5Nxfc3zc9gIgGSGTTGw+E0864BRuAJjhFRF+j5keQ7Rik+PhGnd1\n" + - "P1gAdgB6MoxU2LcttiDqOOBSHumEFnAyE4VNO9IrwTpXo1LrUgAAAYPYTJjXAAAE\n" + - "AwBHMEUCIQDmYqZ1fw/8X2lBl51TknJ8t8sRz4fEFkayqFrmNug1WQIgELQm99K3\n" + - "QH+Rr8rk9x6835NjXBBAyrrI2B8XLiELITUAdwCzc3cH4YRQ+GOG1gWp3BEJSnkt\n" + - "sWcMC4fc8AMOeTalmgAAAYPYTJkaAAAEAwBIMEYCIQD+jnAFon/1Bobh3R4wzym7\n" + - "yiDQ35ZUeRcfFes1IvgyvgIhAPILSf2w3HW7YmbthAVT4P13G+8xFIVlYihgVegU\n" + - "cJy8MBsGCSsGAQQBgjcVCgQOMAwwCgYIKwYBBQUHAwEwPAYJKwYBBAGCNxUHBC8w\n" + - "LQYlKwYBBAGCNxUIh73XG4Hn60aCgZ0ujtAMh/DaHV2Btd1QhZ/9dQIBZAIBHTCB\n" + - "pgYIKwYBBQUHAQEEgZkwgZYwZQYIKwYBBQUHMAKGWWh0dHA6Ly93d3cubWljcm9z\n" + - "b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwRUNDJTIwVExTJTIwSXNz\n" + - "dWluZyUyMEFPQyUyMENBJTIwMDEuY3J0MC0GCCsGAQUFBzABhiFodHRwOi8vb25l\n" + - "b2NzcC5taWNyb3NvZnQuY29tL29jc3AwHQYDVR0OBBYEFN3cgtHESQ8o7thvaL42\n" + - "bD7mpfktMA4GA1UdDwEB/wQEAwIHgDArBgNVHREEJDAigiBydmtlY2Nyb290MjAx\n" + - "Ny5wa2kubWljcm9zb2Z0LmNvbTBoBgNVHR8EYTBfMF2gW6BZhldodHRwOi8vd3d3\n" + - "Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBFQ0MlMjBUTFMl\n" + - "MjBJc3N1aW5nJTIwQU9DJTIwQ0ElMjAwMS5jcmwwZgYDVR0gBF8wXTBRBgwrBgEE\n" + - "AYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t\n" + - "L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMAgGBmeBDAECAjAfBgNVHSMEGDAW\n" + - "gBQxW7nOURt80aoDwOvtNl3CndOJ4TATBgNVHSUEDDAKBggrBgEFBQcDATAKBggq\n" + - "hkjOPQQDAwNoADBlAjBBhbuh/iukcibeEh/Op3RfNf6jUSyza4lZvsJsRiEVwySa\n" + - "ofmg8OvBO2l2+9MjoCUCMQCoiyS1tDgtjW9gguKDgPXypURpL27KfnCzwx6ar2LN\n" + - "gCZ/soGnLsgPIscuNH/BK20=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Fri Oct 14 15:46:18 PDT 2022", System.out); - } -} - -class MicrosoftRSATLS { - - // Owner: CN=Microsoft RSA TLS Issuing AOC CA 01, O=Microsoft Corporation, C=US - // Issuer: CN=Microsoft RSA Root Certificate Authority 2017, O=Microsoft - // Corporation, C=US - // Serial number: 330000002ffaf06f6697e2469c00000000002f - // Valid from: Thu Jun 24 13:57:35 PDT 2021 until: Wed Jun 24 13:57:35 PDT 2026 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIHmDCCBYCgAwIBAgITMwAAAC/68G9ml+JGnAAAAAAALzANBgkqhkiG9w0BAQwF\n" + - "ADBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u\n" + - "MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9y\n" + - "aXR5IDIwMTcwHhcNMjEwNjI0MjA1NzM1WhcNMjYwNjI0MjA1NzM1WjBbMQswCQYD\n" + - "VQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSwwKgYDVQQD\n" + - "EyNNaWNyb3NvZnQgUlNBIFRMUyBJc3N1aW5nIEFPQyBDQSAwMTCCAiIwDQYJKoZI\n" + - "hvcNAQEBBQADggIPADCCAgoCggIBAKAYz8zB6I+LeiWYURf1QUaISydvRgxWfcc6\n" + - "UvEiwvryj2UsRfFuREo2ErLTvP9qQ9E0YBTyWEqI2TXn4jo2uZ2cpGODiQQWlixe\n" + - "aAFcYgSqLzidFXj401vzQsz4E0zylD/ZeY+xkQ6xrdg5312x2u2Ap7AWLzqolZHZ\n" + - "gR0aicn9gcO6M4qn6Uuge8mOve1N7U6j8ebhSiw0KlkzY9ha1Kvrez+NXQdeLC+V\n" + - "PDWPPPlBWeysTnIM6dusbV1v2/C7Ooz9TuGb8wiXRriPpI7+igSIPqBebF00rHGJ\n" + - "Dmx9eN3g78VF9JpTrrRkV8alpMYVZKAh9IzMp9NWVZsw5wgZaX2W05SaXkSHP3zR\n" + - "OBANhKzwkBkCcDMbmF1LFOk+wgkcEtFlKEnfgvOQVHTp02gTzyhSxstw0buon4Cy\n" + - "ZAm1L+6bJJ+puNL8HuLTJxq1mqiaY0T50olJeySSX5uJBo/l29Pz+0WjANnhRLVq\n" + - "e5xdxPV11QGHDxnvsXaMgC4y/5sLo5v4UEZT+4VDcKiRHReusJD+kUt92FSYqWTK\n" + - "xs6zwuxf25as/rJbZT99o9QVFLfHEs6DgHKNIqQuVxZxH0T3M6XqfmnRTo1FrD8i\n" + - "p/93Q4zQta5S9whe/sAxpizwyMw/9fhBDHGVHfgFV1C0EP9zxkyHEya0CGAMhbzp\n" + - "+0Y/ZYxrAgMBAAGjggJJMIICRTAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUB\n" + - "BAMCAQAwHQYDVR0OBBYEFOtMMXw9PzK4g9fF23va5HjanBRXMB0GA1UdJQQWMBQG\n" + - "CCsGAQUFBwMBBggrBgEFBQcDAjAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAS\n" + - "BgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFAnLWX+GsnCPGsM548DZ6b+7\n" + - "TbIjMHAGA1UdHwRpMGcwZaBjoGGGX2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w\n" + - "a2lvcHMvY3JsL01pY3Jvc29mdCUyMFJTQSUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUy\n" + - "MEF1dGhvcml0eSUyMDIwMTcuY3JsMIGuBggrBgEFBQcBAQSBoTCBnjBtBggrBgEF\n" + - "BQcwAoZhaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNy\n" + - "b3NvZnQlMjBSU0ElMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAy\n" + - "MDE3LmNydDAtBggrBgEFBQcwAYYhaHR0cDovL29uZW9jc3AubWljcm9zb2Z0LmNv\n" + - "bS9vY3NwMHAGA1UdIARpMGcwCAYGZ4EMAQIBMAgGBmeBDAECAjBRBgwrBgEEAYI3\n" + - "TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br\n" + - "aW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4ICAQAkucWk\n" + - "Mrgs2ahYrG7y4sY2yZno4f9TGyk7p+Srg4Yz/g7LmVeyOob9o579Omw9AiyeDK8Y\n" + - "/dXnTTof+sKJrlNTpIzyEBkzCiGGkWtp7x2yxLCm12L65wtmD/6OAV9Bm1kOhf3p\n" + - "7v+d3gtFt7cw46W35lr+fguy62s7uuytTV9hfhQ0pp2E2E9F6B7U71jR4bC+6zGq\n" + - "+34AmqTirjKHwXOhWDRDpEJIkaFAh+qdz/nqJktZj3n5GdC94jfWrMUJjClGjlc4\n" + - "+Ws3AxN46oFpx8oIXDG9wIPfFhUf0SdnCYJL8TD5+qBNp0H5q/V2R31Wi8rijHGQ\n" + - "4CxHqzP5VJbjgvRQgxAp39BrmLQ+JSvf9e5VqQqaH4NYgpB1WObq12B73BJHjBOv\n" + - "pRrULFjPqDW8sPRBzBTRXkXOPEdZbzQj6O/CWEFsg6ilO4thk3n3drb9FEJjVh9u\n" + - "GtRXV6Ea5bNaPvJppZNXb7M9mORk3mddx/K1FgOETQE3quh+mU4ojbSRUWMVmjcb\n" + - "6bKF5oQd+Q0do4yaEIfH1oVnIas/FIE/xu3Z4fvBs0qdiNLCeNT6uS26vqD2PEvV\n" + - "lFWb683Do3Ls59MMCxhy6Erb7kFQgu1oUWXGFhbMQkeLN4TXGi6X3loXYfING9om\n" + - "nWa/udxvPRwAZmcHU2l2W8cwVXiy6uucsh3kPQ==\n" + - "-----END CERTIFICATE-----"; - - // Owner: O=Microsoft Corporation, L=Redmond, ST=Washington, C=US - // Issuer: CN=Microsoft RSA TLS Issuing AOC CA 01, O=Microsoft Corporation, C=US - // Serial number: 330000014a3b44c12636e54b9f00000000014a - // Valid from: Fri Oct 14 13:55:34 PDT 2022 until: Mon Oct 09 13:55:34 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIILDCCBhSgAwIBAgITMwAAAUo7RMEmNuVLnwAAAAABSjANBgkqhkiG9w0BAQwF\n" + - "ADBbMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u\n" + - "MSwwKgYDVQQDEyNNaWNyb3NvZnQgUlNBIFRMUyBJc3N1aW5nIEFPQyBDQSAwMTAe\n" + - "Fw0yMjEwMTQyMDU1MzRaFw0yMzEwMDkyMDU1MzRaMFQxCzAJBgNVBAYTAlVTMRMw\n" + - "EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN\n" + - "aWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" + - "AoIBAQDTo/3ysrrKP2eOLQ8JUFhQT09HJM1lUr0nH7RiP4VAKFrGFMIQSCsq17y7\n" + - "PuTHxW53Fvxb5s/EKZobzhlgv4rHQxvoMuGWRBgJN6KfspQAuFnUVG+3y70fHy/O\n" + - "PiVUJdfTupsys/fjzERqzx6FZoU1RzQ08na36SicSOQmj5svtHHxL8ZibDD48Xzp\n" + - "oIEBh2uUDhevkZedBmqlIdAhNgKXqf2lieLjWXZQLzUyXHikQJxNFOHFVjBqH3pu\n" + - "pYt2XD78bS/xeKRbGLw52+o3/u4eaPyiJoG0GaVSG2HRGcplu7Auk6ycD3htispr\n" + - "dviXfHa3tW1hO52PrQBOWvpsP3jdAgMBAAGjggPuMIID6jCCAX4GCisGAQQB1nkC\n" + - "BAIEggFuBIIBagFoAHUA6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4A\n" + - "AAGD2FEl4wAABAMARjBEAiBStVFeTYxl3DxgsM2z7VsvWZ5n7V0SXjnNdgFfmjfL\n" + - "twIgQ6Xfm7oJQDMyBIuPVF0qxLr+EqZ71HDHz5n6g60orlcAdgB6MoxU2LcttiDq\n" + - "OOBSHumEFnAyE4VNO9IrwTpXo1LrUgAAAYPYUSX8AAAEAwBHMEUCIFbeyJxWClLT\n" + - "C1YjUizDHmL5TeKFluRsL0of3NXn7LXuAiEAoZLtiZOie9QLWA66IN3NO8F4VE72\n" + - "m4hZyo0tcJ2FrDkAdwCzc3cH4YRQ+GOG1gWp3BEJSnktsWcMC4fc8AMOeTalmgAA\n" + - "AYPYUSZUAAAEAwBIMEYCIQD7nnuRlDX0iUH+vfbl3aKgn6siy8fL5Dl6HczdPXgD\n" + - "2AIhAJE6xuIKnLOC/BqVG8DydYmhM17TTSK3T98pBtvU9SDcMBsGCSsGAQQBgjcV\n" + - "CgQOMAwwCgYIKwYBBQUHAwEwPAYJKwYBBAGCNxUHBC8wLQYlKwYBBAGCNxUIh73X\n" + - "G4Hn60aCgZ0ujtAMh/DaHV2Btd1QhZ/9dQIBZAIBHTCBpgYIKwYBBQUHAQEEgZkw\n" + - "gZYwZQYIKwYBBQUHMAKGWWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv\n" + - "Y2VydHMvTWljcm9zb2Z0JTIwUlNBJTIwVExTJTIwSXNzdWluZyUyMEFPQyUyMENB\n" + - "JTIwMDEuY3J0MC0GCCsGAQUFBzABhiFodHRwOi8vb25lb2NzcC5taWNyb3NvZnQu\n" + - "Y29tL29jc3AwHQYDVR0OBBYEFJ+DafMSR5RMWJrM6iGS024FVuBYMA4GA1UdDwEB\n" + - "/wQEAwIEsDArBgNVHREEJDAigiBhY3Ryc2Fyb290MjAxNy5wa2kubWljcm9zb2Z0\n" + - "LmNvbTBoBgNVHR8EYTBfMF2gW6BZhldodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v\n" + - "cGtpb3BzL2NybC9NaWNyb3NvZnQlMjBSU0ElMjBUTFMlMjBJc3N1aW5nJTIwQU9D\n" + - "JTIwQ0ElMjAwMS5jcmwwZgYDVR0gBF8wXTBRBgwrBgEEAYI3TIN9AQEwQTA/Bggr\n" + - "BgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1Jl\n" + - "cG9zaXRvcnkuaHRtMAgGBmeBDAECAjAfBgNVHSMEGDAWgBTrTDF8PT8yuIPXxdt7\n" + - "2uR42pwUVzATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQwFAAOCAgEA\n" + - "j80IEKdsV/mWM5LwiS12qjOFzukGhpaFgM4XVQV9QJ/oEwworf7KEFfp4YlrSbtw\n" + - "Wwrh06LESleEfCqY+pbYHUx6ox4LvI5EYu23+YINSdhkTaITFZ1DDrYEHX08r26I\n" + - "rdaTkUOLzP9CRuSw1tbcf0gsj/Dqr8ec3usktccOE6QFbCA9yCsKOr6WdPc4h3PV\n" + - "WKHnpf4n46fZ+N+d7+eAOUZSjqsw/5i6/yiQ0Vx6rBMSKmEzkZx72Xkh9IowCeZJ\n" + - "w/gstrzKepSljWUuNi2iXJB2OuIqydFodLXFc9eeH8MXShDqwFF77nf3R3jMAhvI\n" + - "6fHnEz7+UqhMuyiAU5TfSjC1WyeqHhDZawWPumFyXEh0XX1eUphfoN3bApbZJhEE\n" + - "tyhcz44mGawrjSpxlJGgE5TmKJ+CC73TcBC5Ehelo+Is1gzbbVQCu6gMZQyYS8qf\n" + - "kg+JqJAOfx+YFn4bPAio8uF6XpcvMkcd9dyEYi2Q9zMhnQoOjLWj0pPSQaCBmmbI\n" + - "ougVo16GCOdcOG9+c6dBjbHseaQY0a95ZirtNLbutIvmvMIysvAHMC3NkunnD0cQ\n" + - "BxF47+meDc80QJGCaNlJ8E1SlUbEtRfVNsbcw1skO3hAsYAIA8M//BW7XcKRDvLn\n" + - "nPrC+5fWtDzmXgUE/Sve3rCr/AfBiBrLERcJHxYy41U=\n" + - "-----END CERTIFICATE-----"; - - // Owner: O=Microsoft Corporation, L=Redmond, ST=Washington, C=US - // Issuer: CN=Microsoft RSA TLS Issuing AOC CA 01, O=Microsoft Corporation, C=US - // Serial number: 330000014b4c2b0b9955688feb00000000014b - // Valid from: Fri Oct 14 13:56:58 PDT 2022 until: Mon Oct 09 13:56:58 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIIKjCCBhKgAwIBAgITMwAAAUtMKwuZVWiP6wAAAAABSzANBgkqhkiG9w0BAQwF\n" + - "ADBbMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u\n" + - "MSwwKgYDVQQDEyNNaWNyb3NvZnQgUlNBIFRMUyBJc3N1aW5nIEFPQyBDQSAwMTAe\n" + - "Fw0yMjEwMTQyMDU2NThaFw0yMzEwMDkyMDU2NThaMFQxCzAJBgNVBAYTAlVTMRMw\n" + - "EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN\n" + - "aWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" + - "AoIBAQD2UxPzrv61IqG8jCFPWM3KeQpBeBlxh3mzvWVFmo340r0J1C3uLaUTPYLo\n" + - "P+Xndq2GqYLlm/5FEY7ynU1as57SH0tHbKCIYYJezn/ZJHUYcOY80uGKpP3bdbRq\n" + - "W51Xo7/gzTrXFJ2Nrn05d9mKBq+Oxs71+Nj7QuzjHYAF0n8OWNwZCBOBdAX3EDVQ\n" + - "4HBMSkIzriodM0FD2zkT8RIvZ7WbpLxvZXqWbynAeLirTRYE2lY9UalxrP+wCef9\n" + - "DARxcpEgF30nwRnALfOhnuOhdrtdLYhArfQMyDcvJnDyzCWEZCaPNtBhdsziJjf9\n" + - "A8R4/qdnlQE4/24O9MXQja5dwyyRAgMBAAGjggPsMIID6DCCAXwGCisGAQQB1nkC\n" + - "BAIEggFsBIIBaAFmAHYA6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4A\n" + - "AAGD2FJirgAABAMARzBFAiBct8qI4aiBtisWWMKAtwCueQWAnFtxcrGBiZjwctiB\n" + - "pwIhAPasvYgCS4Rbhb6p2//TCeq0P2H3jUftmi0afwhJYXLaAHUAs3N3B+GEUPhj\n" + - "htYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAGD2FJjIwAABAMARjBEAiBjbry24wGs\n" + - "tpzJFzxWAk7h3IHMKiY1KxIieJMBe7k1dQIgPvDrVgOiUeWlYJmDSdRafTVZHfQg\n" + - "bODj86WqyB5ndt4AdQB6MoxU2LcttiDqOOBSHumEFnAyE4VNO9IrwTpXo1LrUgAA\n" + - "AYPYUmLUAAAEAwBGMEQCIHlmAPOJT2CSJPnupJqbiUOE8nukIuNxaayaEROQQC16\n" + - "AiBufiWDUp9FNjGdZVhjX3t/Bh3iSNrMJD22k5BcNzUbIjAbBgkrBgEEAYI3FQoE\n" + - "DjAMMAoGCCsGAQUFBwMBMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIe91xuB\n" + - "5+tGgoGdLo7QDIfw2h1dgbXdUIWf/XUCAWQCAR0wgaYGCCsGAQUFBwEBBIGZMIGW\n" + - "MGUGCCsGAQUFBzAChllodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Nl\n" + - "cnRzL01pY3Jvc29mdCUyMFJTQSUyMFRMUyUyMElzc3VpbmclMjBBT0MlMjBDQSUy\n" + - "MDAxLmNydDAtBggrBgEFBQcwAYYhaHR0cDovL29uZW9jc3AubWljcm9zb2Z0LmNv\n" + - "bS9vY3NwMB0GA1UdDgQWBBQVaBKJl3UpdKhMrW9owCC3eUdMWzAOBgNVHQ8BAf8E\n" + - "BAMCBLAwKwYDVR0RBCQwIoIgcnZrcnNhcm9vdDIwMTcucGtpLm1pY3Jvc29mdC5j\n" + - "b20waAYDVR0fBGEwXzBdoFugWYZXaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br\n" + - "aW9wcy9jcmwvTWljcm9zb2Z0JTIwUlNBJTIwVExTJTIwSXNzdWluZyUyMEFPQyUy\n" + - "MENBJTIwMDEuY3JsMGYGA1UdIARfMF0wUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYB\n" + - "BQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBv\n" + - "c2l0b3J5Lmh0bTAIBgZngQwBAgIwHwYDVR0jBBgwFoAU60wxfD0/MriD18Xbe9rk\n" + - "eNqcFFcwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEMBQADggIBAFHb\n" + - "lQDG/Jk+kOLRWlZiya00OkZiXrueh4NgfwybZAx3O344+FzP4TsneUys16GO7Pti\n" + - "UTKkxF42INw/3TAC4iOMg4RS4dm+Fn1G7xM59lwqnZLn48a6jORKwZIG0H/2Fevr\n" + - "bGn3ZcTw+NP02OA7X1/ewRfljDZfHNmzdVTSVlqzhliv2cRuZyk7lf1LoIXBTz3Y\n" + - "6ofOjgsP05XEZmMxMwM40FVeslTfuu301plj5KuHpQfbSny0VES3DQnZi+gHX+Zn\n" + - "XuIYQL9stePqQr1GJBqAHM4sRgUCnW5t8efIYDMpYhQynXbniowLGbXOa0OP1IFG\n" + - "oGmhPRonR1aJ2eFBfe0pnc4WO5qdiXQp/XWWYmUJaD7SdGDQF7wH9BUJdldIk6uI\n" + - "SGTh4YD2VAXAGH4e9wHI5t9Lyah/VeBoLU1j3SsJfL6XfcWCwFG2sdqFFQHcONBl\n" + - "ApIjebH4RlOGiRRRJ5/Wz9Wk850mEvF16UlB1MUpLiKU63/nJvuR1TvOisAUl+5L\n" + - "oAfBFVkX4IGJU+9tc4VXYvTpd24xLHk/o6Fnl23D6zWlsZKldNxYPhiriXN9Duvb\n" + - "6xmaQX4gua6jmTFUhKDyyVJpW1A4GjuenPYsCmabzydiAeMIQirCCLSTqXrSw1YL\n" + - "2+608l1nqYy1JOrSq/zFp3c5buSFbjj7jVJB5LEh\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Fri Oct 14 15:46:18 PDT 2022", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +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 - * @bug 8189131 8207059 - * @key intermittent - * @summary Interoperability tests with QuoVadis Root CA1, CA2, and CA3 G3 CAs - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath QuoVadisCA OCSP - * @run main/othervm -Djava.security.debug=certpath QuoVadisCA CRL - */ - -/* - * Obtain TLS test artifacts for QuoVadis CAs from: - * - * https://www.quovadisglobal.com/download-roots-crl/ - * - */ -public class QuoVadisCA { - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - new RootCA1G3().runTest(pathValidator); - new RootCA2G3().runTest(pathValidator); - new RootCA3G3().runTest(pathValidator); - } -} - -class RootCA1G3 { - - // Owner: CN=DigiCert QuoVadis TLS ICA QV Root CA 1 G3, O="DigiCert, Inc", C=US - // Issuer: CN=QuoVadis Root CA 1 G3, O=QuoVadis Limited, C=BM - // Serial number: 2837d5c3c2b57294becf99afe8bbdcd1bb0b20f1 - // Valid from: Wed Jan 06 12:50:51 PST 2021 until: Sat Jan 04 12:50:51 PST 2031 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIFgDCCA2igAwIBAgIUKDfVw8K1cpS+z5mv6Lvc0bsLIPEwDQYJKoZIhvcNAQEL\n" + - "BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\n" + - "BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0yMTAxMDYyMDUwNTFaFw0z\n" + - "MTAxMDQyMDUwNTFaMFkxCzAJBgNVBAYTAlVTMRYwFAYDVQQKDA1EaWdpQ2VydCwg\n" + - "SW5jMTIwMAYDVQQDDClEaWdpQ2VydCBRdW9WYWRpcyBUTFMgSUNBIFFWIFJvb3Qg\n" + - "Q0EgMSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALMrbkb9kz/4\n" + - "y00r7tfK+uDRomMNd5iCDVMWOvSx1VygKoBn3aavw7gq9Vfb2fIMIWkWG0GMxWbG\n" + - "cx3wDHLWemd7yl9MxRUTGXkvH6/dNEavAQhUTL9TSf/N2e8f7q2dRDNYT7lXi/vR\n" + - "fTBiYlY7BLNha8C3sPHsKduaJN32cjdjVFH51rFDRdhUXlo2hhOjgB6bqoqs75A3\n" + - "Y3w88AdbMkapT63oGsCDO6N/uX2Mo9GSWREvlxHiXSMFf5qFw41vn5QIa5ADL1MP\n" + - "CzlLmJSHXE138H1+cG5IutD7tIieKjo/t+66PGMo8xicj3yUd8rHEmBqClG4Ty3d\n" + - "fF+bETFjLIUCAwEAAaOCAU8wggFLMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0j\n" + - "BBgwFoAUo5fW816iEOGrRZ88F2Q87gFwnMwwdAYIKwYBBQUHAQEEaDBmMDgGCCsG\n" + - "AQUFBzAChixodHRwOi8vdHJ1c3QucXVvdmFkaXNnbG9iYWwuY29tL3F2cmNhMWcz\n" + - "LmNydDAqBggrBgEFBQcwAYYeaHR0cDovL29jc3AucXVvdmFkaXNnbG9iYWwuY29t\n" + - "MBMGA1UdIAQMMAowCAYGZ4EMAQICMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEF\n" + - "BQcDATA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3JsLnF1b3ZhZGlzZ2xvYmFs\n" + - "LmNvbS9xdnJjYTFnMy5jcmwwHQYDVR0OBBYEFJkRfemwrS1iWnDTPI2HIK3a2i5B\n" + - "MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAb6tTptzzi4ssb+jA\n" + - "n2O2vAjAo7ydlfN9v+QH0ZuGHlUc9bm8dpNpBo9yt6fWHIprGLJjVOF7HwVDQcJD\n" + - "DhX4638Q7ETDrbTVQ4/edX6Yesq6C1G8Pza1LwStXD/jCQHFvWbPud86V0ikS4rS\n" + - "qlmu3fzUrGZ2/Q+n5jrnRqM5IS8TXYcnzLD3azH1+aZjkwQt9HP4IuvAe/Bg9aWE\n" + - "XeDmksbg0SqQInrWn+BVYtD+hCZNz8K0GnKKpx3Q9VxzRv+BMbO5e9iqK1Hcj5Wv\n" + - "ZXvU45j2r5y9WML4fc8CvphzbF6ezr1e51i+yabNmfld33gRX48V5oNk16wX32ed\n" + - "kQ83sKNomQm1dXURWK8aSDcZFAvJQ8vKTLIE9wiQmtjfSGoJzQhKLaN+egrp4L9y\n" + - "fjpFIeK4zgAH39P4s4kaPWTdfXe2n6P5o7Xolp4R22SVkI76d8d+5Iv7Rtqd+mqI\n" + - "y1hkwyTBbOBLtyF7yMtJQewkkZ0MWxkPvWg193RbYVRx8w1EycnxMgNwy2sJw7MR\n" + - "XM6Mihkw910BkvlbsFUXw4uSvRkkRWSBWVrkM5hvZGtbIJkqrdnj55RSk4DLOOT/\n" + - "LUyji/KpgD7YCi7emFA4tH6OpkNrjUJ3gdRnD4GwQj/87tYeoQWZ6uCl0MHDUCmw\n" + - "73bpxSkjPrYbmKo9mGEAMhW1ZxY=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=quovadis-root-ca-1-g3.chain-demos.digicert.com, O="DigiCert, Inc.", - // L=Lehi, ST=Utah, C=US - // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 1 G3, O="DigiCert, Inc", C=US - // Serial number: a94cc08600f5fe5d3f0659bfcfec6f0 - // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIG/DCCBeSgAwIBAgIQCpTMCGAPX+XT8GWb/P7G8DANBgkqhkiG9w0BAQsFADBZ\n" + - "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDEgRzMwHhcNMjIw\n" + - "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjB9MQswCQYDVQQGEwJVUzENMAsGA1UE\n" + - "CBMEVXRhaDENMAsGA1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x\n" + - "NzA1BgNVBAMTLnF1b3ZhZGlzLXJvb3QtY2EtMS1nMy5jaGFpbi1kZW1vcy5kaWdp\n" + - "Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3HrwaCagg\n" + - "6bxmgEC+neLN/ShfNYuOMQ2Slk5q/zDUhQRpNQnh3nUwoRSWRvwGxDFsRj++LECF\n" + - "TMdfzIu+0rlFzGqd3B5mlRsJrcycy/+ILwGNtIooUSU7pvJAVgLZ5N1SSVZoY+i3\n" + - "bqLiMmv2/JfouT1SQB3U0tGmS+QKyBtVyKPVeuAhnLdyw90UiB7Gu9qXQpCawac8\n" + - "pXPQLFzyEP7VJO0wDXanXvi6YPuIhh4m+j2YVCd9d2zI3y3kOrkuaUY5UCBvMG/b\n" + - "Pc7/5pBsqf+E+7RHF24JAR2aqXzARWt2MzRiwpE/DJDfu097IUtR5aEdCRIKw/b4\n" + - "GcHEbVaE3c8RAgMBAAGjggOaMIIDljAfBgNVHSMEGDAWgBSZEX3psK0tYlpw0zyN\n" + - "hyCt2touQTAdBgNVHQ4EFgQUsG1/1d7ATEocqm82IRByZD/1qQIwOQYDVR0RBDIw\n" + - "MIIucXVvdmFkaXMtcm9vdC1jYS0xLWczLmNoYWluLWRlbW9zLmRpZ2ljZXJ0LmNv\n" + - "bTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" + - "MIGXBgNVHR8EgY8wgYwwRKBCoECGPmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9E\n" + - "aWdpQ2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0ExRzMuY3JsMESgQqBAhj5odHRw\n" + - "Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRRdW9WYWRpc1RMU0lDQVFWUm9v\n" + - "dENBMUczLmNybDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhto\n" + - "dHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggr\n" + - "BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFo\n" + - "dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRRdW9WYWRpc1RMU0lD\n" + - "QVFWUm9vdENBMUczLmNydDAJBgNVHRMEAjAAMIIBfQYKKwYBBAHWeQIEAgSCAW0E\n" + - "ggFpAWcAdgCt9776fP8QyIudPZwePhhqtGcpXc+xDCTKhYY069yCigAAAX9cPNEg\n" + - "AAAEAwBHMEUCIEcb3zz7lhKT26HkZpFPF9e7AsHY4HR3pO5LJ5+b2iDGAiEAjEHh\n" + - "4H3Vl+j95X65uBdkODnqjlxRc6OrqCRor71nKTYAdQA1zxkbv7FsV78PrUxtQsu7\n" + - "ticgJlHqP+Eq76gDwzvWTAAAAX9cPNEMAAAEAwBGMEQCIBbRZ9t9oUODHhZfa7n3\n" + - "0lGGmEpnZP9dZw375SuVX6OjAiBbfpZesx7GgSNygEF+zkBAXx+AFJF5GoGiOjFX\n" + - "0ykjDAB2ALNzdwfhhFD4Y4bWBancEQlKeS2xZwwLh9zwAw55NqWaAAABf1w80SoA\n" + - "AAQDAEcwRQIgfSXjtjuKjFiVYwdlitFNgTTSc7uP9hyazlrCKO9GsaYCIQCKimXl\n" + - "j4LjJ4BlG9H1J+V747tuf7ONnAzkCPsa2ymOuzANBgkqhkiG9w0BAQsFAAOCAQEA\n" + - "b9havJS9egan+4dgMhI6gDt6rjdWRniyi7kXv7/vWJXOxR1xl2d/WYDLsfp3BbqW\n" + - "YuKQwB5tTH1hEoNhQIyGnuE1Y1ZgtX24rSVfTCkU/3dnTZaIhaZgFHyftAum7xSI\n" + - "Qzu7pwih+PXrGNXupsnZ+VUE7a7zHyRDajixhSp7dZS4zLoDTxeyKX0MDmo4e8Mi\n" + - "HNYVASYcrdld90jVJaeI/V3EkJAX7/Eyo9JqzivEwGM0e0JhCLekcVSzhjGoAlbQ\n" + - "tIzCIaeVUlWKKiNXSKr1WD4oCD3ky4Y5VekTGzyUf/0LYzV+Y7p8epc5vTWKwYx/\n" + - "vQwJ4RsgFit+c84mSg4qug==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=quovadis-root-ca-1-g3-revoked.chain-demos.digicert.com, - // O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US - // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 1 G3, O="DigiCert, Inc", C=US - // Serial number: e7eff4cdd14ebed1daa7bb7e07300ed - // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHDjCCBfagAwIBAgIQDn7/TN0U6+0dqnu34HMA7TANBgkqhkiG9w0BAQsFADBZ\n" + - "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDEgRzMwHhcNMjIw\n" + - "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjCBhTELMAkGA1UEBhMCVVMxDTALBgNV\n" + - "BAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu\n" + - "MT8wPQYDVQQDEzZxdW92YWRpcy1yb290LWNhLTEtZzMtcmV2b2tlZC5jaGFpbi1k\n" + - "ZW1vcy5kaWdpY2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n" + - "AQDCQQ2S25TEDDGHa/zvFUex4mD7pUAS7g80g8mQVII2v9Cg6F2tIEbay/IDhV3D\n" + - "NtxJcaqiMpT9oMA5jhMSOqcoq8QFzdqugtIvxQ3obrIZysxjjluB2b1T5UhlnND1\n" + - "ShXlSWRhwkCN8qfO+VJ8wrpVH45mj+DsiSLWrY8Vw4q+gcJgoUV0Vj87m1H93JTf\n" + - "pF68NjljUOOTTXZSzsvTRpDsnOizbVeyZoRawRP8D4UbxA8P28Q5W7a/uZSnUkfo\n" + - "1U1QFDd/ii/PCt6TVGYCNUehb8eSrEyjAtIZ/ricIVkKxcqzQ3Tuq7HefH/KiAqD\n" + - "GWr0NfO1JhX5ILmDZcosdsW1AgMBAAGjggOjMIIDnzAfBgNVHSMEGDAWgBSZEX3p\n" + - "sK0tYlpw0zyNhyCt2touQTAdBgNVHQ4EFgQUK6amWfyhRxRpr+fT1tpYV14n2wgw\n" + - "QQYDVR0RBDowOII2cXVvdmFkaXMtcm9vdC1jYS0xLWczLXJldm9rZWQuY2hhaW4t\n" + - "ZGVtb3MuZGlnaWNlcnQuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr\n" + - "BgEFBQcDAQYIKwYBBQUHAwIwgZcGA1UdHwSBjzCBjDBEoEKgQIY+aHR0cDovL2Ny\n" + - "bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0UXVvVmFkaXNUTFNJQ0FRVlJvb3RDQTFH\n" + - "My5jcmwwRKBCoECGPmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFF1\n" + - "b1ZhZGlzVExTSUNBUVZSb290Q0ExRzMuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQIC\n" + - "MCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBgwYI\n" + - "KwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j\n" + - "b20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp\n" + - "Q2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0ExRzMuY3J0MAkGA1UdEwQCMAAwggF+\n" + - "BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB3AOg+0No+9QY1MudXKLyJa8kD08vREWvs\n" + - "62nhd31tBr1uAAABf1xeMeAAAAQDAEgwRgIhALuEk3mDbnEEkboc95mrKMgibE0K\n" + - "0QAWMu1gI/teH06xAiEA7dbuLv66ScQkOq0zbfnUM8ih1Bw+Wb29jQRyTEXCaxEA\n" + - "dgA1zxkbv7FsV78PrUxtQsu7ticgJlHqP+Eq76gDwzvWTAAAAX9cXjIwAAAEAwBH\n" + - "MEUCIBvEfG23Yewp6oXQJExXQ+Am7z4i0X5NqSz8ohAXT3NiAiEAhDjy2H2Z5CV5\n" + - "gZ8TACTVgNyvEIH0cS4DjH6/ILknLDEAdQCzc3cH4YRQ+GOG1gWp3BEJSnktsWcM\n" + - "C4fc8AMOeTalmgAAAX9cXjJBAAAEAwBGMEQCIGuxWoTPcFYQlVF9q/F1JbaZj/VT\n" + - "O6Oa8ionxCC/8aqrAiAUCUoDcwphZ25ZFC+xGiP0kUiWgUwuQH7lBpTgoZp/BjAN\n" + - "BgkqhkiG9w0BAQsFAAOCAQEAFrVjcQxq81PXEgHCf48+FOle8kUpJGxpH1n1Sp0p\n" + - "V95wrXj47oT1Vt9WqXPrNDfDkxwAvvXrCMXjHEg2YN0FCEanVec8GciuRRRtXrOE\n" + - "QOXAqGv5j+KG7bEvMNUFS90fesxfxVAQkr1zIT70nMAOKV1NOyQ/q8bZ+jehcRZB\n" + - "wUKrCWAzvOw4DPytrDcQmflvQN+Bw92T3uDuoYT/oBcobpVfKpfuW/+ZxxXTIp4L\n" + - "sixlx82SZNTo6e3LOqsgZnR6TFyRJ63sK65M+W0d55bHvleUAHRCOiGhhgqE/cby\n" + - "z50hDzJMLnjskMSpkxMoeSeutAS2e7oIvA//7C37LrQccQ==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) - throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Tue Mar 08 11:22:28 PST 2022", System.out); - } -} - -class RootCA2G3 { - - // Owner: CN=DigiCert QV EV TLS ICA G1, O="DigiCert, Inc.", C=US - // Issuer: CN=QuoVadis Root CA 2 G3, O=QuoVadis Limited, C=BM - // Serial number: 65e9bcd53e791df22dffeb5ecc2bc7a5588d0883 - // Valid from: Mon Mar 16 12:39:42 PDT 2020 until: Thu Mar 14 12:39:42 PDT 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIFbzCCA1egAwIBAgIUZem81T55HfIt/+tezCvHpViNCIMwDQYJKoZIhvcNAQEL\n" + - "BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\n" + - "BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0yMDAzMTYxOTM5NDJaFw0z\n" + - "MDAzMTQxOTM5NDJaMEoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKDA5EaWdpQ2VydCwg\n" + - "SW5jLjEiMCAGA1UEAwwZRGlnaUNlcnQgUVYgRVYgVExTIElDQSBHMTCCASIwDQYJ\n" + - "KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMhwn6I+pGrJsnisnzP7EU5cFN9UT5XF\n" + - "auA13F3jHeUUZmBOcMSOJEhx/e7oeVScTnmKpe7t7uey7lIIC9DWFmP8klbtLBgL\n" + - "0jY4MPlCkVyxUIhZ73EHCPqDCX9bo+rMB6C758/tKZOPcoWRixQypPwoC4cXNOOk\n" + - "ntqFPRxFSZoBdTDNlAmkAQJCRsXGCEC5pZ0JqzGcAA0/Pw1fB8lSPAti3trubYmd\n" + - "aaPFAKzGK7vsexxpuSUKO0opNkFWbLdHZ8jkr86R80oo1vhURJXWNeMS74ws5nbt\n" + - "Ll9sJTDW33MQPS0/JO3xYI7bQcW3K1sPSERa4BahqgOJvEXMk1eWRcUCAwEAAaOC\n" + - "AU0wggFJMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAU7edvdlq/YOxJ\n" + - "W8ald7tyFnGbxD0wOgYIKwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8v\n" + - "b2NzcC5xdW92YWRpc2dsb2JhbC5jb20wSwYDVR0gBEQwQjAHBgVngQwBATA3Bglg\n" + - "hkgBhv1sAgEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29t\n" + - "L0NQUzAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwOwYDVR0fBDQwMjAw\n" + - "oC6gLIYqaHR0cDovL2NybC5xdW92YWRpc2dsb2JhbC5jb20vcXZyY2EyZzMuY3Js\n" + - "MB0GA1UdDgQWBBQTL6fobnFR9uIMmEeDnn+deHk08zAOBgNVHQ8BAf8EBAMCAYYw\n" + - "DQYJKoZIhvcNAQELBQADggIBAEoOxze3kgnR39LX8M63EjiNxx0LThZHROqYqev6\n" + - "5ox/c5NNitk8/ODA8osdPpvnUBAlmE0+gqBvnTBRPVrJFd9bOr5BK8z6Os9/U0ed\n" + - "c3UINkWLS05B7ChC9s6Zw1Vd/WlW08TQJ80GpvAIbEKcg8EO/DXPniHxC4cMtv1T\n" + - "jtNeh98XiVgQXHL1FY+u/l413J8C4utKi4ZOQeCJDqvlSDzRsOi+tHsXrCJxnMWN\n" + - "2QBgMGgdPW37zwf0EffoH0Gee3pTgg7I5SzmvBq0t5xRDfv4N0OdM/sN1mc5f3o7\n" + - "0YCd9WXhyDCV5W2O8QIbrd42CK5k1rlM6gXwOyDmYY5CVAl1QeXEeRfDk/zNjU/1\n" + - "+LnH/Dv88VcZhODYq+VGbyM8bpNr0v95PY3yaH4kzpWGqWAN5i9LosfcaqRPmyL4\n" + - "PcKTQwcA9AVTjITExFua/QtGrXLPvMVxR248G9IQpJMxP3JEGkjlKCenmc29r2u1\n" + - "KE4TeCs2xxjR1PusTfX91bBW3YAoAPDTRQKZjolegLUY44j3uKSzAdhMEbZQhovH\n" + - "Lraqx1WjTayTuq1Vuakcia5shmgFVSNcE+NVgLEIe32oTOm/G6Kd1lcm9C4Ph1Cg\n" + - "nfDuqohZrk76kJTk8poAY5aFCQHhVzbpSw3zooMGjjvWnkG+/DC6SZM8rKoOdKiB\n" + - "cy+N\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=quovadis-root-ca-2-g3.chain-demos.digicert.com, O="DigiCert, - // Inc.", L=Lehi, ST=Utah, C=US, SERIALNUMBER=5299537-0142, OID.1.3.6.1.4 - // 1.311.60.2.1.2=Utah, OID.1.3.6.1.4.1.311.60.2.1.3=US, - // OID.2.5.4 .15=Private Organization - // Issuer: CN=DigiCert QV EV TLS ICA G1, O="DigiCert, Inc.", C=US - // Serial number: 9c5e9d5f169d3a59e64db208d3e849d - // Valid from: Wed Feb 02 16:00:00 PST 2022 until: Mon Mar 06 15:59:59 PST 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHNDCCBhygAwIBAgIQCcXp1fFp06WeZNsgjT6EnTANBgkqhkiG9w0BAQsFADBK\n" + - "MQswCQYDVQQGEwJVUzEXMBUGA1UECgwORGlnaUNlcnQsIEluYy4xIjAgBgNVBAMM\n" + - "GURpZ2lDZXJ0IFFWIEVWIFRMUyBJQ0EgRzEwHhcNMjIwMjAzMDAwMDAwWhcNMjMw\n" + - "MzA2MjM1OTU5WjCB3zEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzAR\n" + - "BgsrBgEEAYI3PAIBAxMCVVMxFTATBgsrBgEEAYI3PAIBAhMEVXRhaDEVMBMGA1UE\n" + - "BRMMNTI5OTUzNy0wMTQyMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDENMAsG\n" + - "A1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xNzA1BgNVBAMTLnF1\n" + - "b3ZhZGlzLXJvb3QtY2EtMi1nMy5jaGFpbi1kZW1vcy5kaWdpY2VydC5jb20wggEi\n" + - "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDfknHK7boXh9ysZ0FLDQKEyT2x\n" + - "Swtyecb5kkVgJU75XpXccV724mntCu5hpZ7Yt4tOmDZvbpYcqWbhIJgxGFNLyPdB\n" + - "Fn8jgZ4N0WoD7u295HI9izEmbM0XrO2rvHUc6ZhFFyx0jhvJPf/k9QbQB4TwKZri\n" + - "Iuf1E1Ek70DkTWAg6OrPHMe2ER3aSz2S2rNkMSopURvZuabzPovsGaz+XEZNfE4N\n" + - "UfkBLa0DUjFCamOMZKIfkzxpH/NhQcigGnZgxiyUb6KRhu9ydpWeOvOHwPWwR/fV\n" + - "7WT+X1DUHojoXeCk2RtIRMihDWPd+lqiUppM8IlEW/gxWbK1wP41qioiK9j5AgMB\n" + - "AAGjggN+MIIDejAfBgNVHSMEGDAWgBQTL6fobnFR9uIMmEeDnn+deHk08zAdBgNV\n" + - "HQ4EFgQUtAEN4g3bzwES6MoOINihiZQrt+owOQYDVR0RBDIwMIIucXVvdmFkaXMt\n" + - "cm9vdC1jYS0yLWczLmNoYWluLWRlbW9zLmRpZ2ljZXJ0LmNvbTAOBgNVHQ8BAf8E\n" + - "BAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHsGA1UdHwR0MHIw\n" + - "N6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFFWRVZUTFNJ\n" + - "Q0FHMS5jcmwwN6A1oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy\n" + - "dFFWRVZUTFNJQ0FHMS5jcmwwSgYDVR0gBEMwQTALBglghkgBhv1sAgEwMgYFZ4EM\n" + - "AQEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMHYG\n" + - "CCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu\n" + - "Y29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln\n" + - "aUNlcnRRVkVWVExTSUNBRzEuY3J0MAwGA1UdEwEB/wQCMAAwggF9BgorBgEEAdZ5\n" + - "AgQCBIIBbQSCAWkBZwB2AOg+0No+9QY1MudXKLyJa8kD08vREWvs62nhd31tBr1u\n" + - "AAABfsHcGW0AAAQDAEcwRQIgSMSWvB5/8sf6CAZYojDI+t3bmcVHtIJT3T+Z3TcZ\n" + - "MFMCIQD5Qyb6jwHOAscsPeID156bUZIw+PeB652u+Q8gTU8C5gB1ADXPGRu/sWxX\n" + - "vw+tTG1Cy7u2JyAmUeo/4SrvqAPDO9ZMAAABfsHcGUcAAAQDAEYwRAIgL68Riq9a\n" + - "l17hobjQopbfzvcQi4KT1+DlqO2dAeCuF80CIAy19t3bAxcJRmbXWo9J2dGc7WuE\n" + - "r+bLfnQoerq9KB1bAHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoA\n" + - "AAF+wdwZZAAABAMARzBFAiEA4vYazXAaD1BfJ8MqEmrfxeTIDQ6LZkmqfh8xEnVz\n" + - "8VYCIF/RgfyBhOeH40wfgwpFTa+Y+t7EWg0PtjC4IaIFTKYKMA0GCSqGSIb3DQEB\n" + - "CwUAA4IBAQC5KLlms/+5XcCIEFBpQSwT7VoRcqnrVWlhya+9ClA98LYuDUeHcHt6\n" + - "lHvfjEEmy2s2GoKHK/JxXzftBau5LbDWlvQ6EF+22fnaVDsKIwNgYwbhJb+6zr8t\n" + - "LOFS6Y51YSlRrDUvy94S3PE7N8D3wyKq18IhXOI1WUeR0bKHLlXtl+ZjKMIMkd/l\n" + - "YtLnnskRCQa0P/HLwQYLUpgiNGVZJQbjrWsVzcw12mR/gza1KjR02STJRGZad7L0\n" + - "Oz48CRhm94iaEjFcVKT3vcDUrtCKpkmhBACcdA3NNqDq10i/SLspOeDLSESkkJKF\n" + - "w8w3YCqXjZn5JyV3sVHYNezNKtLdCxn4\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=quovadis-root-ca-2-g3-revoked.chain-demos.digicert.com, - // O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US, SERIALNUMBER=5299537-0142, - // OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Utah, - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=DigiCert QV EV TLS ICA G1, O="DigiCert, Inc.", C=US - // Serial number: 3f84605850df3ac98fcc15adec269f8 - // Valid from: Sun Apr 17 17:00:00 PDT 2022 until: Fri May 19 16:59:59 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHQDCCBiigAwIBAgIQA/hGBYUN86yY/MFa3sJp+DANBgkqhkiG9w0BAQsFADBK\n" + - "MQswCQYDVQQGEwJVUzEXMBUGA1UECgwORGlnaUNlcnQsIEluYy4xIjAgBgNVBAMM\n" + - "GURpZ2lDZXJ0IFFWIEVWIFRMUyBJQ0EgRzEwHhcNMjIwNDE4MDAwMDAwWhcNMjMw\n" + - "NTE5MjM1OTU5WjCB5zETMBEGCysGAQQBgjc8AgEDEwJVUzEVMBMGCysGAQQBgjc8\n" + - "AgECEwRVdGFoMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEVMBMGA1UE\n" + - "BRMMNTI5OTUzNy0wMTQyMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDENMAsG\n" + - "A1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xPzA9BgNVBAMTNnF1\n" + - "b3ZhZGlzLXJvb3QtY2EtMi1nMy1yZXZva2VkLmNoYWluLWRlbW9zLmRpZ2ljZXJ0\n" + - "LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANfUkoe8l/AFhMH5\n" + - "NtRR2Ztx4xVINz1celdjQE7xgjyHoQY6EMhuI+tvTpwJr9wJEFl7YBiIUFUgJZo6\n" + - "lCLZtXI5t6rN0PhI+F03vGj5ukOkBBcsNVuKPJjud78sHL7u4w7RL3agrQIG7sff\n" + - "bQK4qieUDPxiE8TO8mIzUKnIvYeNA8aJe4zxWf6Mn64WvnudsxYFgMDL4L0ryYKy\n" + - "Ls53Co0OweOl4qnNSne8eIGfb6UaUBQvWbnVfRSHzf+skrF1qstWlFhUsqR07HtF\n" + - "6BqVrAsRA8tmXisyXrMp9jTcIsG7LXVLOqxN07mAvpateExZs3WWRhfQl4Z+HpHD\n" + - "80WbTI0CAwEAAaOCA4IwggN+MB8GA1UdIwQYMBaAFBMvp+hucVH24gyYR4Oef514\n" + - "eTTzMB0GA1UdDgQWBBSTXYbD9dwCDxIH/aN5vIr02uLz5DBBBgNVHREEOjA4gjZx\n" + - "dW92YWRpcy1yb290LWNhLTItZzMtcmV2b2tlZC5jaGFpbi1kZW1vcy5kaWdpY2Vy\n" + - "dC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF\n" + - "BQcDAjB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v\n" + - "RGlnaUNlcnRRVkVWVExTSUNBRzEuY3JsMDegNaAzhjFodHRwOi8vY3JsNC5kaWdp\n" + - "Y2VydC5jb20vRGlnaUNlcnRRVkVWVExTSUNBRzEuY3JsMEoGA1UdIARDMEEwCwYJ\n" + - "YIZIAYb9bAIBMDIGBWeBDAEBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGln\n" + - "aWNlcnQuY29tL0NQUzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6\n" + - "Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2NhY2VydHMu\n" + - "ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0UVZFVlRMU0lDQUcxLmNydDAJBgNVHRMEAjAA\n" + - "MIIBfAYKKwYBBAHWeQIEAgSCAWwEggFoAWYAdQDoPtDaPvUGNTLnVyi8iWvJA9PL\n" + - "0RFr7Otp4Xd9bQa9bgAAAYA+bejFAAAEAwBGMEQCIFDhmaB4BXmOw2SKONPFBU8t\n" + - "qXb7DXeG6JHGcONDqITjAiAqozEj7/1ULu6t/uzfwOSgC7xEmUsLGzQVnaOF9m3s\n" + - "swB1ADXPGRu/sWxXvw+tTG1Cy7u2JyAmUeo/4SrvqAPDO9ZMAAABgD5t6QkAAAQD\n" + - "AEYwRAIgfVEs7Ph+wOpoCGl4woa3aUWH1COGx1SwvHZ8lH21xfsCIBI1IpR6goya\n" + - "iz47tT/Uz+26RnkHiAApYsdMOPyevkzhAHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFn\n" + - "DAuH3PADDnk2pZoAAAGAPm3pPgAABAMARzBFAiAKBon1PVoqJAF49jMQd2c222TK\n" + - "sWkL5sLFqLVZj2vOugIhAODd/OUy236+9alC2U5nxl1oej9fOF4por2OZMFQfpFF\n" + - "MA0GCSqGSIb3DQEBCwUAA4IBAQAyrJzyOiRAETfoYddTmRmbnFNuHx4YAkkdxn2d\n" + - "BXdy4jPn0kTtDo4592KnbTdieSCWghmEmcEY1sQXdX6iqKwzmp408jfUDohl5evV\n" + - "oZrum3P3zgLRz1qswFM5a2HteWzCWWi/n6d6nKXj6PGGVAMQfk1s6PaWhYBuiaag\n" + - "myYss/LTPzaLGUfFzlt/HfomiD+BNuBOVa+pPrmTWhex+e02z95n6RPYCiazuZNZ\n" + - "xiarN83pRNu/fIjVXw2jENg7+kaC1wwLqET0x6/EJa6YI3Xa7Aumb8Pp2r2UZ5Tr\n" + - "7BUhmiRLkvw/9SI8ceXNSwuTTGK2fKHm2/CWqI0cS3zWk3dC\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) - throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon Apr 18 14:07:46 PDT 2022", System.out); - } -} - -class RootCA3G3 { - - // Owner: CN=DigiCert QuoVadis TLS ICA QV Root CA 3 G3, O="DigiCert, Inc", C=US - // Issuer: CN=QuoVadis Root CA 3 G3, O=QuoVadis Limited, C=BM - // Serial number: 427dd33a8ff51d8152e813c7dec93ba76312a7d8 - // Valid from: Wed Jan 06 12:55:40 PST 2021 until: Sat Jan 04 12:55:40 PST 2031 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIFgDCCA2igAwIBAgIUQn3TOo/1HYFS6BPH3sk7p2MSp9gwDQYJKoZIhvcNAQEL\n" + - "BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\n" + - "BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0yMTAxMDYyMDU1NDBaFw0z\n" + - "MTAxMDQyMDU1NDBaMFkxCzAJBgNVBAYTAlVTMRYwFAYDVQQKDA1EaWdpQ2VydCwg\n" + - "SW5jMTIwMAYDVQQDDClEaWdpQ2VydCBRdW9WYWRpcyBUTFMgSUNBIFFWIFJvb3Qg\n" + - "Q0EgMyBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALxNTdqnFD+A\n" + - "MhketYfVfVUWQKPkVEuyYj7Y2uwXBMRP4RStO4CoQih+hX/h94vRlObOIsqcNnyC\n" + - "ElwBnLbmusaWYLYnDEWoROL8uN0pkWk0asfhhEsXTkAJ6FLHUD85WBkED4gIVWPi\n" + - "Sp4AOwiA+/zpbwgVAgdjJTO3jjMsp4F1lBrdViYSwoPRACH1ZMjJG572oXTpZkQX\n" + - "uWmEKLUOnik1i5cbqGLnwXiDvTAhxit7aBlj/C5IDvONWVQL34ZTYppvo8S3Hhy9\n" + - "xX0S4HCpTpeBe3mas7VOrjsXNlEoFvejrxcQ+fB/gUf6fLUPxUhcPtm8keBPQuxc\n" + - "qP12/+KG0WECAwEAAaOCAU8wggFLMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0j\n" + - "BBgwFoAUxhfQvKjqAkPyGwaZXSuQILnXnOQwdAYIKwYBBQUHAQEEaDBmMDgGCCsG\n" + - "AQUFBzAChixodHRwOi8vdHJ1c3QucXVvdmFkaXNnbG9iYWwuY29tL3F2cmNhM2cz\n" + - "LmNydDAqBggrBgEFBQcwAYYeaHR0cDovL29jc3AucXVvdmFkaXNnbG9iYWwuY29t\n" + - "MBMGA1UdIAQMMAowCAYGZ4EMAQICMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEF\n" + - "BQcDATA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3JsLnF1b3ZhZGlzZ2xvYmFs\n" + - "LmNvbS9xdnJjYTNnMy5jcmwwHQYDVR0OBBYEFDNm+y+RBcyzYlLvzTz1fhzOpxeW\n" + - "MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAY0ZuDgyM4I4MO9ll\n" + - "D8qFUPQ8xtcGOuJgSRhDS2onIJ0M8yOGOYJCobIEGIgqyx94kI/n/1Xw+Wvsnhwb\n" + - "OYOtVedx6VGDu6IuSKTVgPPhzwKP5ZA7wtmgKR8+W4E3DM1VerA9Po9ycDK9qCdl\n" + - "K4tuF37grKEzlQKovG+kn0z+Zi0D/E1kN1Q8YmX35HHRenJWKEnAL9QROh0X9jFi\n" + - "SlsHPrxWC3adOdAW+B+kVG0cM2nurd0Ic2YkiLKOOaSd5hbCQY/fCZwohtest+ZU\n" + - "Ajyd+FVzSNvEFrwPzZwKfcdemvD4kew8lx5sG6BUL4GkFWnotxSr+F9Huwgj4pC+\n" + - "cxE2841a/9r/gliuwDM/8jkt16epFAdw0fXemyM8FdHJDnB++3d8SyjOOQ8j+VHW\n" + - "31NWx27sORa5CgRchlldXWDzIIEwbc82a1OAfGUmNAsdEHjMl1HMcZHbjCmdSdsw\n" + - "fmyldZrj2YmvOI5ZlE9z4vzi35KyqlxWCtu9O/SJq/rBvYS0TPmm8HbhJQbeMe6p\n" + - "vJGrxcb1muSBANn9T9wvukjiNNw32ciSDCjZ0h4N+CGxbzoZtgIAQ29IunYdnJix\n" + - "ZiP+ED6xvwgVRBkDSgWD2W/hex/+z4fNmGQJDcri51/tZCqHHv2Y7XReuf4Fk+nP\n" + - "l8Sd/Kpqwde/sJkoqwDcBSJygh0=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=quovadis-root-ca-3-g3.chain-demos.digicert.com, O="DigiCert, Inc.", - // L=Lehi, ST=Utah, C=US - // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 3 G3, O="DigiCert, Inc", C=US - // Serial number: f27ee3fad1d754ae78d7866da0a4f6f - // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIG/jCCBeagAwIBAgIQDyfuP60ddUrnjXhm2gpPbzANBgkqhkiG9w0BAQsFADBZ\n" + - "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDMgRzMwHhcNMjIw\n" + - "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjB9MQswCQYDVQQGEwJVUzENMAsGA1UE\n" + - "CBMEVXRhaDENMAsGA1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x\n" + - "NzA1BgNVBAMTLnF1b3ZhZGlzLXJvb3QtY2EtMy1nMy5jaGFpbi1kZW1vcy5kaWdp\n" + - "Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOZpBBS8yo\n" + - "ioVgFUQDCVcnkHTL4/PfaPKGK1owE0+mKz1AXmYX1rzFfp6gFqjbZeclhWCKoINE\n" + - "OrZ2+1mGp75+nCP89NgoGzPgjYLVsM97gN2Y36/jXu8TwsZdYfBw9gxL+YApvq2r\n" + - "NbPfxXaYfWdq8bz0RzqXRgS8BqKi1q8tKyahx5EJ3fCpozY9NPvCnipwbWXL9evF\n" + - "Oak3c5Ip2YME4mHh8PujrznCVBte7KGLDn2KwbOUbh5SKKBL32vzTPOERWEDMbAu\n" + - "3XqQh/cc4LTp32Lf/XkfnUOSbzNh+Te8ZjeDzI+SYNg9bleKpPxLSkBZyurs4mCD\n" + - "92L8BXPlMaGjAgMBAAGjggOcMIIDmDAfBgNVHSMEGDAWgBQzZvsvkQXMs2JS7808\n" + - "9X4czqcXljAdBgNVHQ4EFgQUnf71SuL2Z73DAgGKgO7UVFDBIkgwOQYDVR0RBDIw\n" + - "MIIucXVvdmFkaXMtcm9vdC1jYS0zLWczLmNoYWluLWRlbW9zLmRpZ2ljZXJ0LmNv\n" + - "bTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" + - "MIGXBgNVHR8EgY8wgYwwRKBCoECGPmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9E\n" + - "aWdpQ2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0EzRzMuY3JsMESgQqBAhj5odHRw\n" + - "Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRRdW9WYWRpc1RMU0lDQVFWUm9v\n" + - "dENBM0czLmNybDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhto\n" + - "dHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggr\n" + - "BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFo\n" + - "dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRRdW9WYWRpc1RMU0lD\n" + - "QVFWUm9vdENBM0czLmNydDAJBgNVHRMEAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8E\n" + - "ggFrAWkAdwDoPtDaPvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAX9cGyUR\n" + - "AAAEAwBIMEYCIQDjpwE/uiXodkY8Cx3ecooM7gxZp+Qi3aQSIi3SWam6YwIhAPqz\n" + - "8AdaOw+FTZApiEiO2PXww8Y98YtivwXay8v/ZFxrAHYANc8ZG7+xbFe/D61MbULL\n" + - "u7YnICZR6j/hKu+oA8M71kwAAAF/XBsk5gAABAMARzBFAiEA4v9FfzFKPr8hPM1O\n" + - "jPSlboD96ufdyFBy9KmD8pFcI6ECIBY6pcURmWtsE/G2jQgC+qvueJqSycNP2qTM\n" + - "iJ3pO/U1AHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAF/XBsl\n" + - "BwAABAMARzBFAiEAsHzOaXv9OIo4RvaKUEscoLpnM98C+4hc6v4Z26d41aICIC2o\n" + - "aTrc5JsqgDhJXp7UArQPziUqDso967W2mrLa0nLdMA0GCSqGSIb3DQEBCwUAA4IB\n" + - "AQC2CaUwlIb+uKsELGw5U2KV0q8uMp/nBIyFaW/HNOJUf8j1keaf31WWBAFfUQVY\n" + - "pzFRUnRmNTtGxCvzyY1YhoQSwswGghz8ZCSQPWCST/Tl8kKuVFas8wSUXaEV23t4\n" + - "G0pfIlXL2oIuJwREjzv54SK7xsQ4whco0nw8DvLt+/5us4t96u8r1EuBKkF45ngz\n" + - "t77MTqpa0nvWUT7q9POT7xwQNui7P0j5t7prVX/fBKm5EfK1Jdi1Toj9+VxTIWYk\n" + - "splUCXw7zxaA3nlrncAmnHxZEY8sQjpGY1OGY0udd+m5bldJNbRTA1Q+VoPVMiU6\n" + - "osdBQGUbbWrqm1fnoFW1VvUt\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=quovadis-root-ca-3-g3-revoked.chain-demos.digicert.com, - // O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US - // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 3 G3, O="DigiCert, Inc", C=US - // Serial number: aafa7cafda91796626f5fc8bcb38702 - // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHDTCCBfWgAwIBAgIQCq+nyv2pF5Zib1/IvLOHAjANBgkqhkiG9w0BAQsFADBZ\n" + - "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDMgRzMwHhcNMjIw\n" + - "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjCBhTELMAkGA1UEBhMCVVMxDTALBgNV\n" + - "BAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu\n" + - "MT8wPQYDVQQDEzZxdW92YWRpcy1yb290LWNhLTMtZzMtcmV2b2tlZC5jaGFpbi1k\n" + - "ZW1vcy5kaWdpY2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n" + - "AQDofDJ1xHHWMhbWwU7e4cY3u2NjvE4ur/A0Y13UK53zoH8qDunV6ORAXQ+zSpev\n" + - "kPlnIbdjYOK1v5RJn2ZRgCafj8Bc/9GnfQ1uE7P9dRkC9ZQwvb6Eh6f4RT7gaOPX\n" + - "UXSXwtr96xdXDvtlJqWx13YQPnSGXUNNT1NH8bs2Myr9j+I5bUcUGsKsGheZoib3\n" + - "6IFINss+ouOhZ+HP6ganS5cQVsUGk5u6BT6oH9VgwfVMjpDqmRkwc6UJmiij/Nz4\n" + - "NOLOx2tivUjhk0eTPUaErUqYipGBSuwww6Linc/0IAIxGJ2k0J3Qz9PthJzG0P47\n" + - "J5U5ej6FimnRS6Rrk5Ywk2HNAgMBAAGjggOiMIIDnjAfBgNVHSMEGDAWgBQzZvsv\n" + - "kQXMs2JS78089X4czqcXljAdBgNVHQ4EFgQU9qXify+xtHlQIniZABL1pv7gcb4w\n" + - "QQYDVR0RBDowOII2cXVvdmFkaXMtcm9vdC1jYS0zLWczLXJldm9rZWQuY2hhaW4t\n" + - "ZGVtb3MuZGlnaWNlcnQuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr\n" + - "BgEFBQcDAQYIKwYBBQUHAwIwgZcGA1UdHwSBjzCBjDBEoEKgQIY+aHR0cDovL2Ny\n" + - "bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0UXVvVmFkaXNUTFNJQ0FRVlJvb3RDQTNH\n" + - "My5jcmwwRKBCoECGPmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFF1\n" + - "b1ZhZGlzVExTSUNBUVZSb290Q0EzRzMuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQIC\n" + - "MCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBgwYI\n" + - "KwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j\n" + - "b20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp\n" + - "Q2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0EzRzMuY3J0MAkGA1UdEwQCMAAwggF9\n" + - "BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB1AOg+0No+9QY1MudXKLyJa8kD08vREWvs\n" + - "62nhd31tBr1uAAABf1wc0LIAAAQDAEYwRAIgdmF6UFe2jgbM3FjYRMmcNaXfpleT\n" + - "E8hmYfmAVy5lSoUCIDPCV27IP9wpdGoxnnCMBwuekg6E4SB0lj49+o9OHHjDAHUA\n" + - "Nc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kwAAAF/XBzQ0QAABAMARjBE\n" + - "AiBO6vYHFci7OWvqDHRlgTn+Q6zNG/LysZEOlrO4W8ZZ2gIgDY5+qjlar3esPN0b\n" + - "JUR5vfITl7UiZoqINJSm1gZ4Nm4AdwCzc3cH4YRQ+GOG1gWp3BEJSnktsWcMC4fc\n" + - "8AMOeTalmgAAAX9cHNDdAAAEAwBIMEYCIQCB52OPhdnYybsWzmkdSGSbgQVmS0V7\n" + - "ZumbThJSJwpuiwIhAP+JRx+Eu3MYRp5iyLb+xlWqghMnDnF9aCfm1VuW4aDuMA0G\n" + - "CSqGSIb3DQEBCwUAA4IBAQBO/4LljBpMGYYxBang12UIQ+FIjxAfKqqIklSa+du2\n" + - "ea0VHqaRrdfh/aTxzb0WaU++bgQN+MeHmQdvwYSgAyU/lY7mIvDTNxFOO6IG2vfR\n" + - "+JAUnS9iVUQ1rXHU72cxUsne5aRyLQ0W/2Zayx85O6/C9gIUJgJVRuk0dTPZ6tnq\n" + - "FoW1S4GwqEpzTuJU8rP5IvMYoYo8jItpjzS0W90gtDvev/XBRs1ig28Ky7ZS5AtQ\n" + - "S2Q6Ikg9YzegE9YNj2wqdZnEneoce0G1InysM/geY1BZ57G9RAUZkzWVTJRLJgbg\n" + - "2nWSqpQJ765gg9JdsRo+zqj1kUBbUYoTSlaAJG6ucrlB\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator) - throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Tue Mar 08 11:23:06 PST 2022", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SSLCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SSLCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SSLCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SSLCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,490 +0,0 @@ -/* - * Copyright (c) 2020, 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. - */ - -/* - * @test - * @bug 8243320 8256895 - * @summary Interoperability tests with SSL.com's RSA, EV RSA, and ECC CA - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath SSLCA OCSP - * @run main/othervm -Djava.security.debug=certpath SSLCA CRL - */ - -/* - * Obtain TLS test artifacts for SSL.com CAs from: - * - * SSL.com RSA CA - * Valid - https://test-dv-rsa.ssl.com - * Revoked - https://revoked-rsa-dv.ssl.com/ - * SSL.com EV RSA CA - * Valid - https://test-ev-rsa.ssl.com - * Revoked - https://revoked-rsa-ev.ssl.com/ - * SSL.com ECC CA - * Valid - https://test-dv-ecc.ssl.com - * Revoked - https://revoked-ecc-dv.ssl.com/ - */ -public class SSLCA { - - public static void main(String[] args) throws Exception { - - System.setProperty("jdk.security.certpath.ocspNonce", "true"); - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - boolean ocspEnabled = false; - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - ocspEnabled = true; - } - - new SSLCA_RSA().runTest(pathValidator, ocspEnabled); - new SSLCA_EV_RSA().runTest(pathValidator, ocspEnabled); - new SSLCA_ECC().runTest(pathValidator, ocspEnabled); - } -} - -class SSLCA_RSA { - - // Owner: CN=SSL.com RSA SSL subCA, O=SSL Corporation, L=Houston, ST=Texas, C=US - // Issuer: CN=SSL.com Root Certification Authority RSA, O=SSL Corporation, L=Houston, ST=Texas, C=US - // Serial number: 997ed109d1f07fc - // Valid from: Fri Feb 12 10:48:52 PST 2016 until: Wed Feb 12 10:48:52 PST 2031 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIGbzCCBFegAwIBAgIICZftEJ0fB/wwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\n" + - "BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK\n" + - "DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp\n" + - "Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTg0ODUyWhcNMzEwMjEyMTg0\n" + - "ODUyWjBpMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv\n" + - "dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjEeMBwGA1UEAwwVU1NMLmNv\n" + - "bSBSU0EgU1NMIHN1YkNBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA\n" + - "hPYpOunhcxiF6xNzl6Tsm/Q89rnu2jVTXTBOZPaBkSD1Ic4lm7qkYwlZ/UgV5nn1\n" + - "5ohhceYDC2AlR9RvGbP+26qrNcuE0XOdHJOB4SoY4d6OqLAQ6ZB0LdERK1Saa5lp\n" + - "QlqHE8936dpr3hGWyqMb2LsdUuhQIzwNkLU/n9HO35irKCbKgS3FeejqkdqK5l6B\n" + - "b11693o4bz9UZCUdBcQ/Xz06tA5cfnHvYkmmjxhj1lLTKwkQhWuIDrpbwWLO0QVO\n" + - "c29s9ieomRKm8sYMyiBG4QqRQ/+bXwp48cF0qAByGWD6b8/gG4Xq1IBgO5p+aWFS\n" + - "0mszkk5rsh4b3XbTHohP3oWQIOV20WWdtVWXiQuBB8RocAl0Ga//b+epiGgME5JX\n" + - "LWXD1aDg/xHy8MUsaMlh6jDfVIFepkPnkwXDpR/n36hpgKa9dErMkgbYeEaPanLH\n" + - "Yd0kv4xQ36PlMMs9WhoDErGcEG9KxAXN4Axr5wl6PTDn/lXcUFvQoIq/5CSP+Kt5\n" + - "jq9tK/gRrAc4AWqRugDvQPYUm00Rqzj5Oxm5NVQYDzbyoA66CD68LETuVrfa9GuW\n" + - "9MAZRO6CDzonAezIdNHsslDb1H8VN/k0zMxjI+0ub4IAmc3I5GfZtvYcpjtMj8L4\n" + - "2TDS34/COov/Pf2HZ/XXGlzjZ7WPmLl4fdB6hhjs2BsCAwEAAaOCAQYwggECMDAG\n" + - "CCsGAQUFBwEBBCQwIjAgBggrBgEFBQcwAYYUaHR0cDovL29jc3BzLnNzbC5jb20w\n" + - "HQYDVR0OBBYEFCYUfuDc16b34tQEJ99h8cLs5zLKMA8GA1UdEwEB/wQFMAMBAf8w\n" + - "HwYDVR0jBBgwFoAU3QQJB6L1en1SUxKSle44gCUNplkwEQYDVR0gBAowCDAGBgRV\n" + - "HSAAMDsGA1UdHwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmxzLnNzbC5jb20vc3NsLmNv\n" + - "bS1yc2EtUm9vdENBLmNybDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYB\n" + - "BQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4ICAQAi6e/iSV5DEqDO6XjQ\n" + - "SIIzXgc255yv6Oc2sqZnvRyVBHtHvo62jMoHY3Xunc/EofbeS4aHdYBvgkn6CNTj\n" + - "VkCU+psWwcT3Pg83uP4k4Thu7bXvrClfS+XBlbJiCF/PSJxLrKnxRn+XIGiYl62H\n" + - "glBhq9K8/fZrI2Qh1mZJmWE0FlxEDCb4i8SBNi8lmDogaFi8/yl32Z9ahmhxcLit\n" + - "DU/XyKA0yOqvIrOGKH95v+/l8fQkzE1VEFvj+iyv4TXd7mRZDOsfqfIDZhrpou02\n" + - "kXH/hcXlrR++t8kjj9wt8HHQ+FkryWI6bU3KPRJR6N8EH2EHi23Rp8/kyMs+gwaz\n" + - "zMqnkNPbMME723rXk6/85sjOUaZCmhmRIx9rgqIWQesU962J0FruGOOasLT7WbZi\n" + - "FsmSblmpjUAo49sIRi7X493qegyCEAa412ynybhQ7LVsTLEPxVbdmGVih3jVTif/\n" + - "Nztr2Isaaz4LpMEo4mGCiGxec5mKr1w8AE9n6D91CvxR5/zL1VU1JCVC7sAtkdki\n" + - "vnN1/6jEKFJvlUr5/FX04JXeomIjXTI8ciruZ6HIkbtJup1n9Zxvmr9JQcFTsP2c\n" + - "bRbjaT7JD6MBidAWRCJWClR/5etTZwWwWrRCrzvIHC7WO6rCzwu69a+l7ofCKlWs\n" + - "y702dmPTKEdEfwhgLx0LxJr/Aw==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=test-dv-rsa.ssl.com - // Issuer: CN=SSL.com RSA SSL subCA, O=SSL Corporation, L=Houston, ST=Texas, C=US - // Serial number: 4ceada4ade82a6ccd0b2ae32c0dbfd62 - // Valid from: Fri Jun 28 07:06:50 PDT 2019 until: Sun Jun 27 07:06:50 PDT 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHTjCCBTagAwIBAgIQTOraSt6CpszQsq4ywNv9YjANBgkqhkiG9w0BAQsFADBp\n" + - "MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24x\n" + - "GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjEeMBwGA1UEAwwVU1NMLmNvbSBSU0Eg\n" + - "U1NMIHN1YkNBMB4XDTE5MDYyODE0MDY1MFoXDTIxMDYyNzE0MDY1MFowHjEcMBoG\n" + - "A1UEAwwTdGVzdC1kdi1yc2Euc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" + - "ADCCAQoCggEBAKlOrYr8fnHN8REfJDwgsBhJvnsU4beQIYYaOAzR8pmo8eq1U/K0\n" + - "uwRrgJ5K61V78zBO5qmZNiivBobViftObWrq2H6QhQsYdMYXld3SEnEotIIriRHY\n" + - "2PcqlgnFYXkqI0ZKs4kNs+j3GS0IwncJJwKtypmtLTCLK5J/kG7qB2MNfXZTIzKI\n" + - "iZza4RUM1j67Hv3fPJzNEJ9urfjaI4xcRh5airlzBWOBU9pW87P7BgQN7cNzJQji\n" + - "4DSvb1pSXv8sBbZk5fmG+81PyUxcfqj7Dbih0J1Aoq0YysHugsrK/kLz+CvqL9B2\n" + - "a1JMZfob9jzcA7XPjpggLc3az2Wvv3XKqokCAwEAAaOCAzswggM3MB8GA1UdIwQY\n" + - "MBaAFCYUfuDc16b34tQEJ99h8cLs5zLKMHwGCCsGAQUFBwEBBHAwbjBKBggrBgEF\n" + - "BQcwAoY+aHR0cDovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkvU1NMY29tLVN1YkNB\n" + - "LVNTTC1SU0EtNDA5Ni1SMS5jcnQwIAYIKwYBBQUHMAGGFGh0dHA6Ly9vY3Nwcy5z\n" + - "c2wuY29tMDcGA1UdEQQwMC6CE3Rlc3QtZHYtcnNhLnNzbC5jb22CF3d3dy50ZXN0\n" + - "LWR2LXJzYS5zc2wuY29tMFEGA1UdIARKMEgwCAYGZ4EMAQIBMDwGDCsGAQQBgqkw\n" + - "AQMBATAsMCoGCCsGAQUFBwIBFh5odHRwczovL3d3dy5zc2wuY29tL3JlcG9zaXRv\n" + - "cnkwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMDoGA1UdHwQzMDEwL6At\n" + - "oCuGKWh0dHA6Ly9jcmxzLnNzbC5jb20vU1NMY29tUlNBU1NMc3ViQ0EuY3JsMB0G\n" + - "A1UdDgQWBBQD/cmwQI853u0mOlmCjNRsAZOlEDAOBgNVHQ8BAf8EBAMCBaAwggF+\n" + - "BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLY\n" + - "gwDEe4l6qP3LAAABa55yL0QAAAQDAEcwRQIgWo8UQY3EYwyzkGLBLS0Zxu7oMmB7\n" + - "dnpzsEcoexWzZrQCIQCR6FkAe5ns84x2phRkn6nV7a0anjnxjpJUNeCfc3/pxAB2\n" + - "AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABa55yLzsAAAQDAEcw\n" + - "RQIhAKhGKQIpSd59tJm/Yac7Xo05u93CWbnDwoDgSMS+HBs5AiAfOSOc3BzY/2MF\n" + - "AM4GWrkK5Ehs9JMafo/+VBM0OrwVKQB2AId1v+dZfPiMQ5lfvfNu/1aNR1Y2/0q1\n" + - "YMG06v9eoIMPAAABa55yL4IAAAQDAEcwRQIhANcF26iGoUuzZL6rGKduPtyyYusf\n" + - "03lBKSyvxabB9WuvAiBNbxR210L+JP89s/ONw53lYVr+1m/c3u9/9Wpu7c3n5jAN\n" + - "BgkqhkiG9w0BAQsFAAOCAgEACX2CbVM8MCIJ+2Wsap1v6VU2kpCS/FBIsLSTWNEf\n" + - "dREv1nh93qQ2CPIxj5kP/0EOUfq7tmQCJHMODVgz3iHrdxRB1E58nXHlZ6vUdrCo\n" + - "pD9d6Cp+AwvrOdv6MndVJgel9tVOAqAUblwdLzPNQHEcXoKnFEVv2SVQCmAYLlkP\n" + - "xX2RS73gseiit4QnVZOWi/wDhqMm7/iq8n7rL/f7+ly2+7e3LVjxd24HZkgxNgbn\n" + - "JDjYvIla+EvyrY8514Ru3Pf1UICY03VpYjE8R7SxrqcvOLtwvOVew6TuCUl6RNpl\n" + - "xeC9Oa1dgf+QRXN7LvmBXUP2nOCnwJE1ENvThPLw9BXLatVJgkA/v/mYWE5VjzIL\n" + - "hboPH2fNWemUv5QMzxUkqhgHgrhr8wnhI6xYIYciGDbmmfnItHex7bxktT7axoCD\n" + - "3dTQQe01YfK/LlkHtnBmJf/t0F33m8KXcQ51fic/TR2U5Tampxp2kdFdTyvRRqMl\n" + - "igqo3EhiPmB9bKsnXDA2AnvdjZT9uFwbUu5lNxjiMQcSZikjQAjJPgjCZ9BQOGbL\n" + - "eqgZcw2CxWMxFSTLL3TIBlNL/0GpRlTvr3IGyvHEr7EESXKD+Ar8XW+4VlMc1s8F\n" + - "cdtnus71s7wm+JUSXcM0WJUkRUvWqHlPi3Ucfe7k6x6BG9Mb42ECjorefPXvFu7v\n" + - "OT4=\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked-rsa-dv.ssl.com - // Issuer: CN=SSL.com RSA SSL subCA, O=SSL Corporation, L=Houston, ST=Texas, C=US - // Serial number: 3f527e677d00558272ac90d1620b67f4 - // Valid from: Fri Jun 28 07:13:48 PDT 2019 until: Sun Jun 27 07:13:48 PDT 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHVzCCBT+gAwIBAgIQP1J+Z30AVYJyrJDRYgtn9DANBgkqhkiG9w0BAQsFADBp\n" + - "MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24x\n" + - "GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjEeMBwGA1UEAwwVU1NMLmNvbSBSU0Eg\n" + - "U1NMIHN1YkNBMB4XDTE5MDYyODE0MTM0OFoXDTIxMDYyNzE0MTM0OFowITEfMB0G\n" + - "A1UEAwwWcmV2b2tlZC1yc2EtZHYuc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD\n" + - "ggEPADCCAQoCggEBAMKtMVeo+fMoeu1nLrcwxNAdfUysNKEhNZbMUOu9pzCChEvJ\n" + - "QHUicdrIZYl9m59uKUMh3Dj2nJLZ3a0pP4iWKcOEfCVMtA83/GDJl/BVj3XFbsMl\n" + - "+HSIu7R0vQM4enOztLabnOzvE4pQOFUp8u5SKO+hmB0zQ1iWkevYjJOf5DBZ7Zsa\n" + - "uF4qy9JqSF07gj/7FNqmqnfy6Z8yc8WAMjoUJrVrvmHQZeX/bCWxczFhYmAtYlwO\n" + - "7a914VP79b3Jq60HbLbYBdILnuU1Uu5L/JbG+hm/fH2meY30aWUaKcGY04ej6xuM\n" + - "hWsLhOrmcl3P7/E5UUojaR1Zvdtsn7jkQ8Y3iOsCAwEAAaOCA0EwggM9MB8GA1Ud\n" + - "IwQYMBaAFCYUfuDc16b34tQEJ99h8cLs5zLKMHwGCCsGAQUFBwEBBHAwbjBKBggr\n" + - "BgEFBQcwAoY+aHR0cDovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkvU1NMY29tLVN1\n" + - "YkNBLVNTTC1SU0EtNDA5Ni1SMS5jcnQwIAYIKwYBBQUHMAGGFGh0dHA6Ly9vY3Nw\n" + - "cy5zc2wuY29tMD0GA1UdEQQ2MDSCFnJldm9rZWQtcnNhLWR2LnNzbC5jb22CGnd3\n" + - "dy5yZXZva2VkLXJzYS1kdi5zc2wuY29tMFEGA1UdIARKMEgwCAYGZ4EMAQIBMDwG\n" + - "DCsGAQQBgqkwAQMBATAsMCoGCCsGAQUFBwIBFh5odHRwczovL3d3dy5zc2wuY29t\n" + - "L3JlcG9zaXRvcnkwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMDoGA1Ud\n" + - "HwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmxzLnNzbC5jb20vU1NMY29tUlNBU1NMc3Vi\n" + - "Q0EuY3JsMB0GA1UdDgQWBBSTrHG0Sh+8BEp+oP+avIGAtSdyajAOBgNVHQ8BAf8E\n" + - "BAMCBaAwggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB2AESUZS6w7s6vxEAH2Kj+\n" + - "KMDa5oK+2MsxtT/TM5a1toGoAAABa554kQsAAAQDAEcwRQIhAIfU+5HWDnqZdlMN\n" + - "Z+CEkBE8wBFUWzG0ixSQ5S1Tryt4AiAQevLU7OF3N90zIt2QpwVAIGve5lBElhMH\n" + - "fRqXTkeZZwB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABa554\n" + - "jJQAAAQDAEcwRQIhAPd8mNiDFHA74Bl16nwOPehQZmiFltzCYDsd0uHv5qCfAiB+\n" + - "S43G7Yhq62Ofma6wXsag+UEl/tttzfbfASGz1WPBOQB2AKS5CZC0GFgUh7sTosxn\n" + - "cAo8NZgE+RvfuON3zQ7IDdwQAAABa554kDoAAAQDAEcwRQIgUs8O4gQ34Sp0K4Dn\n" + - "Wh7FRFJWwZ6cGYvqmKT+UyCeVisCIQDl0AYXsn4ILMafvmJwnXlcduZ3z6P0jwGK\n" + - "Cjh26ETDFzANBgkqhkiG9w0BAQsFAAOCAgEAAtTlh2YMwe6E0+EWKU3H79NmgLjK\n" + - "xoR3VtT56ILRt0qJuJ+z1iqq/IxZBe7wnUUWU46SWmBfDEQcGI7Hdomr67QBZNZz\n" + - "+wvnatMzrCPM7jPsb05Motz99NSk6yzQzR2c030sy1d78mRKJ/4wpidNDHpjuYL9\n" + - "cBp2gKf2/RxU74+BhugCjLqB1gojGO0CT1/g5a1QMtqRMM0EPrJrrtcEM0zG48yI\n" + - "P3b57Nl2ZbshRvY9bVi3of2SaPFQgu99/zAlerPUThz4O2CskOgKt77y6KOgCbBp\n" + - "7fQF6vh/aOm0Xba2Z0CtB+uVN2g4+LwyuovOy+JyjGKv7GxRKEQmGZsRLDVpxOs5\n" + - "W47K+iuOEhTRWRkStfuk2LcCLwTrgxHv2/Wo+80ME/7wxGKs1IzlkcFtFLhaeN4p\n" + - "QsmADpcyBfeWmvTdKgaVBOE2F/nenIiKpo+0jcoMAW6JgMD+otn8gofBq+Za1N4X\n" + - "xckvLWbMDAj4lELBHXu7gLHHLJCL9GGPD5HKjH/RyLtKKaRgT/AV6jl/woKTAzGF\n" + - "SPqgNQsu+sCdUbO0nDONkXDxhfan8XNrd32KMPGucJySiyjpHkurobMuGbs/LQzd\n" + - "JLTSTIIIPpEHBk7PHRGPSFewIhi0aDhupgZLU9UGrLRw/xV/KlGqTcGFWBvvOC+I\n" + - "CSZFRr0hWBv/dfw=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Fri Jun 28 07:25:02 PDT 2019", System.out); - } -} - -class SSLCA_EV_RSA { - - // Owner: CN=SSL.com EV SSL Intermediate CA RSA R3, O=SSL Corp, L=Houston, ST=Texas, C=US - // Issuer: CN=SSL.com EV Root Certification Authority RSA R2, O=SSL Corporation, L=Houston, ST=Texas, C=US - // Serial number: 56b629cd34bc78f6 - // Valid from: Wed May 31 11:14:37 PDT 2017 until: Fri May 30 11:14:37 PDT 2042 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIG4DCCBMigAwIBAgIQA6P00GAwUqM3zjgKiDAxjDANBgkqhkiG9w0BAQsFADCB\n" + - "gjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9u\n" + - "MRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNzA1BgNVBAMMLlNTTC5jb20gRVYg\n" + - "Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EgUjIwHhcNMTkwMzI2MTc0\n" + - "NjUzWhcNMzQwMzIyMTc0NjUzWjByMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4\n" + - "YXMxEDAOBgNVBAcMB0hvdXN0b24xETAPBgNVBAoMCFNTTCBDb3JwMS4wLAYDVQQD\n" + - "DCVTU0wuY29tIEVWIFNTTCBJbnRlcm1lZGlhdGUgQ0EgUlNBIFIzMIICIjANBgkq\n" + - "hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkby+CNUTyO0wakMc6VeJxQLGcTtfwJG6\n" + - "W9MYhMBWW22YUMtfCL7at/ey89eCc0cNy9uekJqitJe78Ion5qHBLfSpahYWttzr\n" + - "LflXkdlPz6xsZuw7F/tp6oYrcUpRIX92ci0EhORtb5xoX7rwzrBnG2Jv7fPn8JGj\n" + - "wmvYPS0meVkuKGtdR/s3dkl0tDraq2xti8cN7W9VawzLDL9yNyEw2GWAp3M5Uqex\n" + - "Yjh9HY5w/4bgk7K0KSw+2njaXCEa2MugM6txHDKjocVFBe7G8JPMKkCcbbrgZo/q\n" + - "ygTnIY8q7B1XQG2wrdsu4LTo9ijIYmoZHBAKN/XCdPecQYF9cHrv6NjVUcMrNmHT\n" + - "B43NrIvrXmm3lZJU4PZNUhb7YrDtpN+rV6zSaKAu/EArGDzYv8iHKT2E+wjhwqOC\n" + - "WnXv1qSa//xvN6RSoDMpj7q7iTxfdrQqRFsr70hyPrUmnoJLrBBg1+IqFTkaNtuk\n" + - "misP4Bd0zeqkEuxYCmhKcCTM2iS9RMCIot5HI5qeAcVs63WzM+ax0zbHK1F9AIOG\n" + - "gwrVRrdwXRSXO4TlvamsL6klJMnjSCs7E1l8xeE403nZPp4RGr5ZQFrhfdG9nL7w\n" + - "66osGX+dGHGZkFjASS3Bw0RCiz4oCJxFGE+FAD7pJaV8GP6XTkaZp9n1ooYzCC48\n" + - "vq0OtfRS62MCAwEAAaOCAV8wggFbMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0j\n" + - "BBgwFoAU+WC71OPVNPa49QaAJadz20ZpqJ4wfAYIKwYBBQUHAQEEcDBuMEoGCCsG\n" + - "AQUFBzAChj5odHRwOi8vd3d3LnNzbC5jb20vcmVwb3NpdG9yeS9TU0xjb20tUm9v\n" + - "dENBLUVWLVJTQS00MDk2LVIyLmNydDAgBggrBgEFBQcwAYYUaHR0cDovL29jc3Bz\n" + - "LnNzbC5jb20wEQYDVR0gBAowCDAGBgRVHSAAMB0GA1UdJQQWMBQGCCsGAQUFBwMC\n" + - "BggrBgEFBQcDATBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3Jscy5zc2wuY29t\n" + - "L1NTTGNvbS1Sb290Q0EtRVYtUlNBLTQwOTYtUjIuY3JsMB0GA1UdDgQWBBS/wVqH\n" + - "/yj6QT39t0/kHa+gYVgpvTAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD\n" + - "ggIBAAoTAGRea1Lg+Rlvnhj6lHbvhn9mjUlXZuI1b4d4jDDk5X29gNKhW7Rg97Qt\n" + - "oBoJaLb9gZkJ2MkUbCE1x2jIghjLmmFvaIq+nAZEMtWWEi0ycqQm8rVUHioZ2Mfn\n" + - "2SoFtQeY+5MFLO9l8IeDaNZ+LV3su8YTsh/453vExhiNhPVEqLyGlkkW0B2gNW8z\n" + - "bsRy6L5QW0cZ4gZrY86MvHB0Gl299mTJ4jcgic+Oalbz9SZJ+EiW/aUDSpZ2zawi\n" + - "ackPWmAbk0y0gouOymrwOJZTuq+AJEJ6M+WSVdknwE7YwDpVMszHXS38BS1A5N1i\n" + - "rzW3BcARHbtCb00vEy2mzW5JPM2LjkzfgJ0lBiyDCE3ZeBeUtKmcdFUFrHwHl3gV\n" + - "aRipD+xMa1hGOTh33eMzwWoRxvk6o7y73Sy6XBfycN+8LhXUZT0X8STmWtBtLSMp\n" + - "blWMjuuFyUVQvIj05N7hORY/LhdQhEx8kVwS5RkLVSpRnohdk+nI69yIA7EwZKlw\n" + - "kKEsDqlVOeDYWVWQANDC55kJ7nOyJbqtGJqImwWXdQcf37fi80cf+mKOYs5vNmkx\n" + - "D9bwFWsKnP71x0liSlv8z79vRAo8FJwTgXRNO1c0ACf0rXEJy3GRAXRWiTvuGahR\n" + - "JVM3Jnn0G6o3+vTfwa7CKR/9Jc4t25iRU3xmSgiusg4u8i5x\n" + - "-----END CERTIFICATE-----"; - - // Owner: OID.1.3.6.1.4.1.311.60.2.1.3=US, OID.1.3.6.1.4.1.311.60.2.1.2=Nevada, STREET=3100 Richmond Ave, - // OID.2.5.4.15=Private Organization, OID.2.5.4.17=77098, CN=test-ev-rsa.ssl.com, SERIALNUMBER=NV20081614243, - // O=SSL Corp, L=Houston, ST=Texas, C=US - // Issuer: CN=SSL.com EV SSL Intermediate CA RSA R3, O=SSL Corp, L=Houston, ST=Texas, C=US - // Serial number: 558089b221d7cd9c7a4bc4a7fd7e2969 - // Valid from: Mon Jul 01 13:28:01 PDT 2019 until: Wed Jun 30 13:28:01 PDT 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIISTCCBjGgAwIBAgIQVYCJsiHXzZx6S8Sn/X4paTANBgkqhkiG9w0BAQsFADBy\n" + - "MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24x\n" + - "ETAPBgNVBAoMCFNTTCBDb3JwMS4wLAYDVQQDDCVTU0wuY29tIEVWIFNTTCBJbnRl\n" + - "cm1lZGlhdGUgQ0EgUlNBIFIzMB4XDTE5MDcwMTIwMjgwMVoXDTIxMDYzMDIwMjgw\n" + - "MVowgfExCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91\n" + - "c3RvbjERMA8GA1UECgwIU1NMIENvcnAxFjAUBgNVBAUTDU5WMjAwODE2MTQyNDMx\n" + - "HDAaBgNVBAMME3Rlc3QtZXYtcnNhLnNzbC5jb20xDjAMBgNVBBEMBTc3MDk4MR0w\n" + - "GwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEaMBgGA1UECQwRMzEwMCBSaWNo\n" + - "bW9uZCBBdmUxFzAVBgsrBgEEAYI3PAIBAgwGTmV2YWRhMRMwEQYLKwYBBAGCNzwC\n" + - "AQMTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsmMOHfREGN48\n" + - "nlgxYiF0EJsytoM98UAslRRlGHJyZw3SLcPx9u/I82h0KKjLtnY3/o62mCoEZYlc\n" + - "1UKKEIi3NgByU8yJ0yynm3I0LJHEZqOKoahtzwP787/OtqsSsWeblrTnfxVO7G1J\n" + - "bPYrPtNuQ9ZnmByyhA+hlTIY48kJh5WtmBeftBSynuKCgpVnkv2y2LKZJc4t6JQX\n" + - "XO6Geev8LPUd2uPVjatZv0se2YKdixFQQKwWcLJV5LZqjZDhZtPomCN0sp+wle4p\n" + - "rRTZPSWRB98mI1X+UBTFGFKS9cxzO2NwmVcbgN2WYR+FpWbatoS/RThGC7mKQB7i\n" + - "5BEQHNZMawIDAQABo4IDWTCCA1UwHwYDVR0jBBgwFoAUv8Fah/8o+kE9/bdP5B2v\n" + - "oGFYKb0wfwYIKwYBBQUHAQEEczBxME0GCCsGAQUFBzAChkFodHRwOi8vd3d3LnNz\n" + - "bC5jb20vcmVwb3NpdG9yeS9TU0xjb20tU3ViQ0EtRVYtU1NMLVJTQS00MDk2LVIz\n" + - "LmNydDAgBggrBgEFBQcwAYYUaHR0cDovL29jc3BzLnNzbC5jb20wNwYDVR0RBDAw\n" + - "LoITdGVzdC1ldi1yc2Euc3NsLmNvbYIXd3d3LnRlc3QtZXYtcnNhLnNzbC5jb20w\n" + - "XwYDVR0gBFgwVjAHBgVngQwBATANBgsqhGgBhvZ3AgUBATA8BgwrBgEEAYKpMAED\n" + - "AQQwLDAqBggrBgEFBQcCARYeaHR0cHM6Ly93d3cuc3NsLmNvbS9yZXBvc2l0b3J5\n" + - "MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBIBgNVHR8EQTA/MD2gO6A5\n" + - "hjdodHRwOi8vY3Jscy5zc2wuY29tL1NTTGNvbS1TdWJDQS1FVi1TU0wtUlNBLTQw\n" + - "OTYtUjMuY3JsMB0GA1UdDgQWBBTIDVTF3DDhdwudatuodPyHe1jcOzAOBgNVHQ8B\n" + - "Af8EBAMCBaAwggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB1AG9Tdqwx8DEZ2JkA\n" + - "pFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABa69CQcUAAAQDAEYwRAIgEYzpfp8v+gG3\n" + - "S9cgZIuFCKPeoSM85gag8/iBJhNIb9oCIDcq+2Pi8+E3LAVmZfgcMhg30t821LNn\n" + - "PWATU5+gAmmzAHUAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFr\n" + - "r0JCCQAABAMARjBEAiAzeyNw/2osk+xktY8VpFTsROj7jRODS2G3G2MDV6ZmMwIg\n" + - "bwuFbNxSEqUfKhveZJVVLYzZtzXcjkhflaazupumZrkAdwC72d+8H4pxtZOUI5eq\n" + - "kntHOFeVCqtS6BqQlmQ2jh7RhQAAAWuvQkGUAAAEAwBIMEYCIQCEfoPIKoy0Rv/d\n" + - "DXOVm0FzKDH2zWHN/oQZ/7gwd21hvAIhAL2gDESf+tcjCkbjdj9NpDa/fVWO9VZD\n" + - "uPPnAZ6jf2G3MA0GCSqGSIb3DQEBCwUAA4ICAQAcYH/+o9N0E3H9h0GfohGElfRw\n" + - "XPUnQI3/CZwuG0ShCbpVspvUkuR/P0Hjr9XgDVy39R9SOaEDK3/coG8/Ry56Lrm0\n" + - "17v+yeEzAVK51eQeinHoCYc9TIwmyrwt36JE/zIwnDB623Y4ccxYN5LZxjVx668/\n" + - "xj3JffaY5185qPjAqkjLUzj9TeeAJk/ws1YXbQJvO4CZV2QXrishC+dEoqvfOe/u\n" + - "sMHcMJy+cFrPhe4cC7s9fHeYTpF36yvfWrgjGwDki/9zgRhOvDuM72dIMkrcHkZi\n" + - "OvZMgyoXz/Nw3D514K9BSt6xRB2qGzI8fx0EOGzEEjX1Zdie2uVDy9aC8k8TjQAM\n" + - "v/YT7Bggpv300hWvBGw0QT8l7Nk1PZFBagAhqRCKRsR1pUZ8CyZzwNkNyUSYV4Or\n" + - "n0vYwVEgpMeSMu/ObWwWPM7QKSNcSSIV5lxmsZX+wS76OpDMHm27P94RTEePF4sG\n" + - "QmvY6hgHSlREJUL0vyGGY2Rbm3cL3zaM4qTquN18v61uUVKakELYIcRZwVTyBj5M\n" + - "KxOkjGXnLYpDOLFHD4WB1q7J+SorG43V+nbmTEN5fshGUjjWoz5ykfErnyJa1+Py\n" + - "FXWoPFb425DelhuDe94btROuJELRfzhqDXoKrhDgSQGV2qM3sk6uIPOaoH4N31ko\n" + - "C41bezSdJ5r4mif8iA==\n" + - "-----END CERTIFICATE-----"; - - // Owner: OID.1.3.6.1.4.1.311.60.2.1.3=US, OID.1.3.6.1.4.1.311.60.2.1.2=Nevada, STREET=3100 Richmond Ave, - // OID.2.5.4.15=Private Organization, OID.2.5.4.17=77098, CN=revoked-rsa-ev.ssl.com, SERIALNUMBER=NV20081614243, - // O=SSL Corp, L=Houston, ST=Texas, C=US - // Issuer: CN=SSL.com EV SSL Intermediate CA RSA R3, O=SSL Corp, L=Houston, ST=Texas, C=US - // Serial number: 1ea7f53492bded2d425135bdf525889f - // Valid from: Mon Jul 01 13:29:02 PDT 2019 until: Wed Jun 30 13:29:02 PDT 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIIUzCCBjugAwIBAgIQHqf1NJK97S1CUTW99SWInzANBgkqhkiG9w0BAQsFADBy\n" + - "MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24x\n" + - "ETAPBgNVBAoMCFNTTCBDb3JwMS4wLAYDVQQDDCVTU0wuY29tIEVWIFNTTCBJbnRl\n" + - "cm1lZGlhdGUgQ0EgUlNBIFIzMB4XDTE5MDcwMTIwMjkwMloXDTIxMDYzMDIwMjkw\n" + - "MlowgfQxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91\n" + - "c3RvbjERMA8GA1UECgwIU1NMIENvcnAxFjAUBgNVBAUTDU5WMjAwODE2MTQyNDMx\n" + - "HzAdBgNVBAMMFnJldm9rZWQtcnNhLWV2LnNzbC5jb20xDjAMBgNVBBEMBTc3MDk4\n" + - "MR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEaMBgGA1UECQwRMzEwMCBS\n" + - "aWNobW9uZCBBdmUxFzAVBgsrBgEEAYI3PAIBAgwGTmV2YWRhMRMwEQYLKwYBBAGC\n" + - "NzwCAQMTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlqZwW2n7\n" + - "Ot8ujRGyCkzf/FqkiIi6+mq7QXlBMsZVNmLcWzatoS9K8WOviU+lmYpdV3rkrX1v\n" + - "e/FZBwtBR/x1FRN3CPoGcO0Yu6CZjknHtyyNQ36mwUy7UW+rQKYjDfU4aXme4bP8\n" + - "Dk2rUYQtM/xpYHKDk9x7Vg4zAmk+L0LQmSU0103DRuANnxOszEK196UbLE4W+2+i\n" + - "Xat40jHW3KU2PxVfCajgB1mdrDt2b5j/qDAL+Wo2DzCtE62UPJvI6UyEqJ24jinS\n" + - "A4l4NgkMPDMWNU5QIkV/EhQvZMUKCvNUv+Gsq8pcOeDXxKpBIe/KoQSMH18mym1U\n" + - "vIaTjAzDDsWjqwIDAQABo4IDYDCCA1wwHwYDVR0jBBgwFoAUv8Fah/8o+kE9/bdP\n" + - "5B2voGFYKb0wfwYIKwYBBQUHAQEEczBxME0GCCsGAQUFBzAChkFodHRwOi8vd3d3\n" + - "LnNzbC5jb20vcmVwb3NpdG9yeS9TU0xjb20tU3ViQ0EtRVYtU1NMLVJTQS00MDk2\n" + - "LVIzLmNydDAgBggrBgEFBQcwAYYUaHR0cDovL29jc3BzLnNzbC5jb20wPQYDVR0R\n" + - "BDYwNIIWcmV2b2tlZC1yc2EtZXYuc3NsLmNvbYIad3d3LnJldm9rZWQtcnNhLWV2\n" + - "LnNzbC5jb20wXwYDVR0gBFgwVjAHBgVngQwBATANBgsqhGgBhvZ3AgUBATA8Bgwr\n" + - "BgEEAYKpMAEDAQQwLDAqBggrBgEFBQcCARYeaHR0cHM6Ly93d3cuc3NsLmNvbS9y\n" + - "ZXBvc2l0b3J5MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBIBgNVHR8E\n" + - "QTA/MD2gO6A5hjdodHRwOi8vY3Jscy5zc2wuY29tL1NTTGNvbS1TdWJDQS1FVi1T\n" + - "U0wtUlNBLTQwOTYtUjMuY3JsMB0GA1UdDgQWBBQnclOL04VraXmRZEkhwgMbajmy\n" + - "YTAOBgNVHQ8BAf8EBAMCBaAwggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB3AG9T\n" + - "dqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABa69DLjEAAAQDAEgwRgIh\n" + - "AMd3B9Gt/hpTCZ+2xsOTTKBaDjh+EsMcKuwZkEpO6UN0AiEA8yiZ9ZIrCOUxsdQp\n" + - "FJi+MtsNQxvgu8igdv+l34jHZA0AdgCHdb/nWXz4jEOZX73zbv9WjUdWNv9KtWDB\n" + - "tOr/XqCDDwAAAWuvQy52AAAEAwBHMEUCIQCFPALMZd6xk4NgYuTXoJGo/FRX0Wub\n" + - "VWSgTZQwld5fTQIgDDp8vajs+7R7XyKOv41xP26NQ3zR4EegwOGeb0paiIIAdQC7\n" + - "2d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWuvQy4MAAAEAwBGMEQC\n" + - "IGFiEQ8fMrjm1bV/mbT35bvJWf4mUbb92/NkHkQvHcaQAiBcS4CclZmzQLj4w6CV\n" + - "JsLf1P6+OhCDtvxWZdndGwJRczANBgkqhkiG9w0BAQsFAAOCAgEAFwE/RMAk871D\n" + - "acLlB0Jb29+WBmCgIu1pA+bh5/lMxn5KoPxkbHPFVHlfenDgZHUNU6DKH4HdCUG7\n" + - "GSAyajLiYRkcrDtBfp5MtNUAqnOJbh2NWiJ3FgSdAjfeSXPhhGfQ3U+0YCWarBfO\n" + - "xZ49eyhTzhHMoW+caJV3jC442Ebzh2X243MwcxqIkjgzWs6duiHnpHfT9gZBl3ou\n" + - "eu85LVFwzxNdrrAx1yG9PA05wCsYYlzwx7fC8ycfbvs+2ORIztiEScyr9VCg5sho\n" + - "YGuBFuP38sWRwiV5K7+EqpGjY+4R3BLWol7lzWsqWJC1J4zkd6Df5reSGBt0wlbx\n" + - "7MdUTXzHMtP8NDIYpdMBrPbkzOKIDzO6bDMsBWWFz7rWCmxUI6sSf0yknPtmBgCd\n" + - "rJAq25V/DqSRGrkaY4Dx1CPGtwYN34fCDLxKeN69rG5mkR2w7HRR5eMXek6oi3Pr\n" + - "hQrKt5NgrYjO6HJ6ABI5xoDM9doXy9BYbz5RX43RTU399aIqyXZh0d3W0rr7wggt\n" + - "+PFRU1OJqhpPQgKsB5zFT3G2HgVBD0hawHS+0Hu+CHpngiDziH+eyvTk3tdhIq2x\n" + - "oDZXs7SSZK6hf/im+7OFSkROy6CwhAn3nxRI9lpag1tTgF4kVSctBv+301ev0twX\n" + - "0w6RymKcvEbcuSDHkzOYWxc1cqwOxjA=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Mon Jul 01 20:53:13 PDT 2019", System.out); - } -} - -class SSLCA_ECC { - - // Owner: CN=SSL.com SSL Intermediate CA ECC R2, O=SSL Corp, L=Houston, ST=Texas, C=US - // Issuer: CN=SSL.com Root Certification Authority ECC, O=SSL Corporation, L=Houston, ST=Texas, C=US - // Serial number: 75e6dfcbc1685ba8 - // Valid from: Fri Feb 12 10:14:03 PST 2016 until: Tue Feb 12 10:14:03 PST 2041 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIDejCCAv+gAwIBAgIQHNcSEt4VENkSgtozEEoQLzAKBggqhkjOPQQDAzB8MQsw\n" + - "CQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24xGDAW\n" + - "BgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBSb290IENl\n" + - "cnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzAeFw0xOTAzMDcxOTQyNDJaFw0zNDAz\n" + - "MDMxOTQyNDJaMG8xCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UE\n" + - "BwwHSG91c3RvbjERMA8GA1UECgwIU1NMIENvcnAxKzApBgNVBAMMIlNTTC5jb20g\n" + - "U1NMIEludGVybWVkaWF0ZSBDQSBFQ0MgUjIwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n" + - "AASEOWn30uEYKDLFu4sCjFQ1VupFaeMtQjqVWyWSA7+KFljnsVaFQ2hgs4cQk1f/\n" + - "RQ2INSwdVCYU0i5qsbom20rigUhDh9dM/r6bEZ75eFE899kSCI14xqThYVLPdLEl\n" + - "+dyjggFRMIIBTTASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFILRhXMw\n" + - "5zUE044CkvvlpNHEIejNMHgGCCsGAQUFBwEBBGwwajBGBggrBgEFBQcwAoY6aHR0\n" + - "cDovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkvU1NMY29tLVJvb3RDQS1FQ0MtMzg0\n" + - "LVIxLmNydDAgBggrBgEFBQcwAYYUaHR0cDovL29jc3BzLnNzbC5jb20wEQYDVR0g\n" + - "BAowCDAGBgRVHSAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA7BgNV\n" + - "HR8ENDAyMDCgLqAshipodHRwOi8vY3Jscy5zc2wuY29tL3NzbC5jb20tZWNjLVJv\n" + - "b3RDQS5jcmwwHQYDVR0OBBYEFA10Zgpen+Is7NXCXSUEf3Uyuv99MA4GA1UdDwEB\n" + - "/wQEAwIBhjAKBggqhkjOPQQDAwNpADBmAjEAxYt6Ylk/N8Fch/3fgKYKwI5A011Q\n" + - "MKW0h3F9JW/NX/F7oYtWrxljheH8n2BrkDybAjEAlCxkLE0vQTYcFzrR24oogyw6\n" + - "VkgTm92+jiqJTO5SSA9QUa092S5cTKiHkH2cOM6m\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=test-dv-ecc.ssl.com - // Issuer: CN=SSL.com SSL Intermediate CA ECC R2, O=SSL Corp, L=Houston, ST=Texas, C=US - // Serial number: 1bfbd8e4bea894f3d1887c50e7d366d7 - // Valid from: Fri Jun 28 06:58:27 PDT 2019 until: Sun Jun 27 06:58:27 PDT 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIE9TCCBHqgAwIBAgIQG/vY5L6olPPRiHxQ59Nm1zAKBggqhkjOPQQDAzBvMQsw\n" + - "CQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24xETAP\n" + - "BgNVBAoMCFNTTCBDb3JwMSswKQYDVQQDDCJTU0wuY29tIFNTTCBJbnRlcm1lZGlh\n" + - "dGUgQ0EgRUNDIFIyMB4XDTE5MDYyODEzNTgyN1oXDTIxMDYyNzEzNTgyN1owHjEc\n" + - "MBoGA1UEAwwTdGVzdC1kdi1lY2Muc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49\n" + - "AwEHA0IABJ5u0b8BID+8+TKxn+os0rdwvWB7mUJ4lcCthTADMhnr1VUWBbmBEelB\n" + - "666WbvbVXooPMUbhE5JvhXCTDyI7RRmjggNHMIIDQzAfBgNVHSMEGDAWgBQNdGYK\n" + - "Xp/iLOzVwl0lBH91Mrr/fTB7BggrBgEFBQcBAQRvMG0wSQYIKwYBBQUHMAKGPWh0\n" + - "dHA6Ly93d3cuc3NsLmNvbS9yZXBvc2l0b3J5L1NTTGNvbS1TdWJDQS1TU0wtRUND\n" + - "LTM4NC1SMi5jcnQwIAYIKwYBBQUHMAGGFGh0dHA6Ly9vY3Nwcy5zc2wuY29tMDcG\n" + - "A1UdEQQwMC6CE3Rlc3QtZHYtZWNjLnNzbC5jb22CF3d3dy50ZXN0LWR2LWVjYy5z\n" + - "c2wuY29tMFEGA1UdIARKMEgwCAYGZ4EMAQIBMDwGDCsGAQQBgqkwAQMBATAsMCoG\n" + - "CCsGAQUFBwIBFh5odHRwczovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkwHQYDVR0l\n" + - "BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6\n" + - "Ly9jcmxzLnNzbC5jb20vU1NMY29tLVN1YkNBLVNTTC1FQ0MtMzg0LVIyLmNybDAd\n" + - "BgNVHQ4EFgQUGCTbprTbVmmNOgJjUgiHonbu8b8wDgYDVR0PAQH/BAQDAgeAMIIB\n" + - "gQYKKwYBBAHWeQIEAgSCAXEEggFtAWsAdwCHdb/nWXz4jEOZX73zbv9WjUdWNv9K\n" + - "tWDBtOr/XqCDDwAAAWueaoEnAAAEAwBIMEYCIQCdy3N9w0pem1XShE/rkVSpHxQb\n" + - "8QdUu3E6R+oncxOGXgIhAJoWg2gJYc9DWDl5ImnrqsmVS6OPgSQRvDsjRIN9gH7a\n" + - "AHcAu9nfvB+KcbWTlCOXqpJ7RzhXlQqrUugakJZkNo4e0YUAAAFrnmqArQAABAMA\n" + - "SDBGAiEAs2yfi9e1h6dTQbe4WPd7+5qf7kvP7Vr2k0nAtBS1IgECIQCQYL9he9J4\n" + - "Bh5cpQezTVPgLAOGcf5xIcCrBs1QJe66/AB3AFWB1MIWkDYBSuoLm1c8U/DA5Dh4\n" + - "cCUIFy+jqh0HE9MMAAABa55qgaEAAAQDAEgwRgIhAI/27txsvzpbBXkMICi/UOzE\n" + - "t8uZidbF9KSwmGRPT/6gAiEAhm/VeWHDeWK8gFMU+f0/x4jK7UbzySGBvPzbPpNd\n" + - "EDwwCgYIKoZIzj0EAwMDaQAwZgIxAJKn8Hr68Z/2rA+VHfZo8eeIFaZ3nvSvQO92\n" + - "1Byl6cPAm8DsdCnYT16uNSL8Zb5IQAIxAOFLsqPDCSAYkpgutAnVgwI+c549SIRU\n" + - "k8ol+wUx6zgMmt8VHYagyj6IO0GRDjm/eA==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked-ecc-dv.ssl.com - // Issuer: CN=SSL.com SSL Intermediate CA ECC R2, O=SSL Corp, L=Houston, ST=Texas, C=US - // Serial number: 423c2b57dfa379d0c45ffceb6284ed99 - // Valid from: Fri Jun 28 07:09:30 PDT 2019 until: Sun Jun 27 07:09:30 PDT 2021 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIE+TCCBH+gAwIBAgIQQjwrV9+jedDEX/zrYoTtmTAKBggqhkjOPQQDAzBvMQsw\n" + - "CQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24xETAP\n" + - "BgNVBAoMCFNTTCBDb3JwMSswKQYDVQQDDCJTU0wuY29tIFNTTCBJbnRlcm1lZGlh\n" + - "dGUgQ0EgRUNDIFIyMB4XDTE5MDYyODE0MDkzMFoXDTIxMDYyNzE0MDkzMFowITEf\n" + - "MB0GA1UEAwwWcmV2b2tlZC1lY2MtZHYuc3NsLmNvbTBZMBMGByqGSM49AgEGCCqG\n" + - "SM49AwEHA0IABH4nWtnAwPIdcQOSNI72IJJ/I1ZL2XQUAfa3ox5taFQQAalng6N9\n" + - "Od9t9de1vIMDzUvs5sMWw4YrqAlywFKMraajggNJMIIDRTAfBgNVHSMEGDAWgBQN\n" + - "dGYKXp/iLOzVwl0lBH91Mrr/fTB7BggrBgEFBQcBAQRvMG0wSQYIKwYBBQUHMAKG\n" + - "PWh0dHA6Ly93d3cuc3NsLmNvbS9yZXBvc2l0b3J5L1NTTGNvbS1TdWJDQS1TU0wt\n" + - "RUNDLTM4NC1SMi5jcnQwIAYIKwYBBQUHMAGGFGh0dHA6Ly9vY3Nwcy5zc2wuY29t\n" + - "MD0GA1UdEQQ2MDSCFnJldm9rZWQtZWNjLWR2LnNzbC5jb22CGnd3dy5yZXZva2Vk\n" + - "LWVjYy1kdi5zc2wuY29tMFEGA1UdIARKMEgwCAYGZ4EMAQIBMDwGDCsGAQQBgqkw\n" + - "AQMBATAsMCoGCCsGAQUFBwIBFh5odHRwczovL3d3dy5zc2wuY29tL3JlcG9zaXRv\n" + - "cnkwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMEQGA1UdHwQ9MDswOaA3\n" + - "oDWGM2h0dHA6Ly9jcmxzLnNzbC5jb20vU1NMY29tLVN1YkNBLVNTTC1FQ0MtMzg0\n" + - "LVIyLmNybDAdBgNVHQ4EFgQUY7q+xN9nV1nPQ/dJ5rUC8OKgaoMwDgYDVR0PAQH/\n" + - "BAQDAgeAMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdQBElGUusO7Or8RAB9io\n" + - "/ijA2uaCvtjLMbU/0zOWtbaBqAAAAWuedJ/tAAAEAwBGMEQCIGPBF546Tn/lzB22\n" + - "ICpFLOWOIyIOPwL9S4ikS8Vt1aFTAiBe8mp/WCJnV7WxMIVWEUSLVOYn7erwyu6D\n" + - "hWNIST4W8wB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABa550\n" + - "oQEAAAQDAEcwRQIhAJ3nwLI7kLP2SKicFKuJoqRYKE/FR2Ff65WL+iWxm/6nAiAJ\n" + - "cd9EKnBETwM9qQfKoSSs2oTQL4QjSKJZi/sPfKQaagB2ALvZ37wfinG1k5Qjl6qS\n" + - "e0c4V5UKq1LoGpCWZDaOHtGFAAABa550oH4AAAQDAEcwRQIhAIo6k5BMSFN3FnD4\n" + - "UFbyJJG/Bujh+OFTYzVM8vuIBoU0AiAhBe+air4wHvd68ykK6xOPv9Qshje9F6LC\n" + - "gxTqbMOEkDAKBggqhkjOPQQDAwNoADBlAjEAyayBtbcCQB0fE+cCc7OHLuNvb9tl\n" + - "uiHWy/Ika6IA72WJLLmED971ik08OMa2mGt4AjAklxdElQ5Z/nSeJ2CNEwD7pcYz\n" + - "468kkrMoGU2lk3QmwcXZscPIoh4Pwew6QteY4J0=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Fri Jun 28 07:59:20 PDT 2019", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TWCAGlobalCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -/* - * 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 8305975 - * @summary Interoperability tests with TWCA Global Root CA from TAIWAN-CA - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath TWCAGlobalCA OCSP - * @run main/othervm -Djava.security.debug=certpath TWCAGlobalCA CRL - */ - -/* - * Obtain TLS test artifacts for TWCA Global Root CA from: - * - * Valid TLS Certificates: - * https://evssldemo6.twca.com.tw - * - * Revoked TLS Certificates: - * https://evssldemo7.twca.com.tw - */ -public class TWCAGlobalCA { - - // Owner: CN=TWCA Global EVSSL Certification Authority, OU=Global EVSSL Sub-CA, O=TAIWAN-CA, C=TW - // Issuer: CN=TWCA Global Root CA, OU=Root CA, O=TAIWAN-CA, C=TW - // Serial number: 40013304f70000000000000cc042cd6d - // Valid from: Thu Aug 23 02:53:30 PDT 2012 until: Fri Aug 23 08:59:59 PDT 2030 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIFdzCCA1+gAwIBAgIQQAEzBPcAAAAAAAAMwELNbTANBgkqhkiG9w0BAQsFADBR\n" + - "MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290\n" + - "IENBMRwwGgYDVQQDExNUV0NBIEdsb2JhbCBSb290IENBMB4XDTEyMDgyMzA5NTMz\n" + - "MFoXDTMwMDgyMzE1NTk1OVowczELMAkGA1UEBhMCVFcxEjAQBgNVBAoTCVRBSVdB\n" + - "Ti1DQTEcMBoGA1UECxMTR2xvYmFsIEVWU1NMIFN1Yi1DQTEyMDAGA1UEAxMpVFdD\n" + - "QSBHbG9iYWwgRVZTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqG\n" + - "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7MIaeq4wMnTjA5C2LsR6HJUj6rZbs8Nmq\n" + - "sSqFoqu6LwjrMbzkAg274EL6913MQ6eOy6VUDRzqAfgBEYcwFofe/w8nC7Q6Nrzz\n" + - "xTkl9lovXLJIm0CI44Qk2IhiCkoYaPlIoqexqnm3Fc2QRdRNeLk2pU/s86DpGrwT\n" + - "BqRRRkziBlhcgo7K5Z9ihf+c82DT31iIUIi2nr0ES1eaRR7zpKrzJPZ8foNxRPwT\n" + - "2D0tJWQJ4hNzbFGSKsSzshdwQ/p4JP9AEjK2eeXXbEePt0/JarwBjO2Lwign38/g\n" + - "0ZiP3uE47bItxZhgXlnR5L/0bhJitE6U1xgVFbbrQnG2B2kZxVKxAgMBAAGjggEn\n" + - "MIIBIzAfBgNVHSMEGDAWgBRI283ejulJclqI6LHYPQezuWtmUDAdBgNVHQ4EFgQU\n" + - "br2hK87kwtUodFy92YxvBHIqBt4wDgYDVR0PAQH/BAQDAgEGMDgGA1UdIAQxMC8w\n" + - "LQYEVR0gADAlMCMGCCsGAQUFBwIBFhdodHRwOi8vd3d3LnR3Y2EuY29tLnR3LzBJ\n" + - "BgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vUm9vdENBLnR3Y2EuY29tLnR3L1RXQ0FS\n" + - "Q0EvZ2xvYmFsX3Jldm9rZV80MDk2LmNybDASBgNVHRMBAf8ECDAGAQH/AgEAMDgG\n" + - "CCsGAQUFBwEBBCwwKjAoBggrBgEFBQcwAYYcaHR0cDovL1Jvb3RPY3NwLnR3Y2Eu\n" + - "Y29tLnR3LzANBgkqhkiG9w0BAQsFAAOCAgEAaOmLaZ2+WN2EtB6feuSV5KnL88ck\n" + - "I9jsUTB4YtKsv0ViORkeBMCQur5OoAgRE9VYdRVlWHN0zJAX232fdoZmnajl8gtj\n" + - "u0AOOyDDJ7Vlh38rDMRlX/u+MS2DFcsq5Vd3EMwJsWWFR9D3Dcey+Tu9uEmEdqeB\n" + - "+Erd4YjCeV9PyOW3SzPQ47RdW6XYmHArPh65/LcmSxTn/lxQy/NEBGGWqhm6s6n1\n" + - "49mPq4MtQcMLo/NBI+8jv7BVjnThbbEh2edHHxMNiAd5kLZFDCyJuFkoezjWL4AH\n" + - "ratXdoHtqvqtPoy97LyGrLrJeh+0hkO9u8QOt2gF7BEhNfid7o5dnsPRk+8l77Hn\n" + - "T1dvBs++M0r0QG4AWMSMj9uUn6rhl4FGTvAsyB1fA8p/xCLoIEetIpKRP3BD+ve2\n" + - "eYjWPorR/0W77iMTeoQEeuxDIxi2J/U9QLKKvzzqBy1TYrqqPe5YxqHLNAcfHZvo\n" + - "BTPPbtP0WAiXrJiELTYcqFXETvQcGw0XjoUZNvJE8RD7vssSNT17RKU8iBRX7CbL\n" + - "AB3T8gYykPMJTUqQSmdgEdVRBcqRMMdU+XRAEoU/Mz5oHAkm3ZNTDNwsEp2Dg1/b\n" + - "qzfPMhg4/3/YyWzGrzNeCSWZkjYImAzLCvN0D5rbdVHEmFIrEJt+igocGozroq5x\n" + - "DT5KhixlrqexzWE=\n" + - "-----END CERTIFICATE-----"; - - // Owner: OID.2.5.4.17=100, STREET="10F.,NO.85,Yanping S. Rd.,Taipei City 100,Taiwan (R.O.C)", - // SERIALNUMBER=70759028, OID.1.3.6.1.4.1.311.60.2.1.3=TW, OID.1.3.6.1.4.1.311.60.2.1.2=Taiwan, - // OID.1.3.6.1.4.1.311.60.2.1.1=Taipei, OID.2.5.4.15=Private Organization, - // CN=evssldemo6.twca.com.tw, O=TAIWAN-CA INC., L=Taipei, ST=Taiwan, C=TW - // Issuer: CN=TWCA Global EVSSL Certification Authority, OU=Global EVSSL Sub-CA, - // O=TAIWAN-CA, C=TW - // Serial number: 47e70000001258ff71d89af7f0353fef - // Valid from: Thu Mar 02 00:49:56 PST 2023 until: Sun Mar 31 08:59:59 PDT 2024 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIH7zCCBtegAwIBAgIQR+cAAAASWP9x2Jr38DU/7zANBgkqhkiG9w0BAQsFADBz\n" + - "MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRwwGgYDVQQLExNHbG9i\n" + - "YWwgRVZTU0wgU3ViLUNBMTIwMAYDVQQDEylUV0NBIEdsb2JhbCBFVlNTTCBDZXJ0\n" + - "aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0yMzAzMDIwODQ5NTZaFw0yNDAzMzExNTU5\n" + - "NTlaMIIBMzELMAkGA1UEBhMCVFcxDzANBgNVBAgTBlRhaXdhbjEPMA0GA1UEBxMG\n" + - "VGFpcGVpMRcwFQYDVQQKEw5UQUlXQU4tQ0EgSU5DLjEfMB0GA1UEAxMWZXZzc2xk\n" + - "ZW1vNi50d2NhLmNvbS50dzEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + - "FzAVBgsrBgEEAYI3PAIBARMGVGFpcGVpMRcwFQYLKwYBBAGCNzwCAQITBlRhaXdh\n" + - "bjETMBEGCysGAQQBgjc8AgEDEwJUVzERMA8GA1UEBRMINzA3NTkwMjgxQTA/BgNV\n" + - "BAkTODEwRi4sTk8uODUsWWFucGluZyBTLiBSZC4sVGFpcGVpIENpdHkgMTAwLFRh\n" + - "aXdhbiAoUi5PLkMpMQwwCgYDVQQREwMxMDAwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" + - "DwAwggEKAoIBAQDEgj/jtcAtGPkiBilLajzHIqfiAxpwwnKhdHwyOnqfcqur1p2R\n" + - "Cxl0Q8jYGmY8ZUq7716XnIGN3bn3Wu10BvmHi07h8f54/G/K7xBKjkasAh44zW1P\n" + - "hgdaxH0huRvoQOoSRCitew8YpMN4B++uOQ8yu2pWDGDdQHW4VaWt/e+QtZbQtp/b\n" + - "7vUWgcuhxDStj97B8Dcb5PY+sbLy6dfDiXnTaSpuWhjKmEcpknagGyn4uCFBSppZ\n" + - "/PYcTsg+Nk8Ae/SDMpc7XWBCjmxMG2GI0IVW4un9UOuElYgWVjMWnBAiGMDkVMEQ\n" + - "jLRxEYOh+NJ3izMyD/ufLrA/YwJMI1LgFcOJAgMBAAGjggO7MIIDtzAfBgNVHSME\n" + - "GDAWgBRuvaErzuTC1Sh0XL3ZjG8EcioG3jAdBgNVHQ4EFgQUg4msPcTFvDjwluRf\n" + - "inEn9qMC7OYwUwYDVR0fBEwwSjBIoEagRIZCaHR0cDovL3NzbHNlcnZlci50d2Nh\n" + - "LmNvbS50dy9zc2xzZXJ2ZXIvR2xvYmFsRVZTU0xfUmV2b2tlXzIwMTIuY3JsMCEG\n" + - "A1UdEQQaMBiCFmV2c3NsZGVtbzYudHdjYS5jb20udHcwfwYIKwYBBQUHAQEEczBx\n" + - "MEQGCCsGAQUFBzAChjhodHRwOi8vc3Nsc2VydmVyLnR3Y2EuY29tLnR3L2NhY2Vy\n" + - "dC9HbG9iYWxFdnNzbF8yMDEyLnA3YjApBggrBgEFBQcwAYYdaHR0cDovL2V2c3Ns\n" + - "b2NzcC50d2NhLmNvbS50dy8wSAYDVR0gBEEwPzA0BgwrBgEEAYK/JQEBFgMwJDAi\n" + - "BggrBgEFBQcCARYWaHR0cDovL3d3dy50d2NhLmNvbS50dzAHBgVngQwBATAJBgNV\n" + - "HRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" + - "BQUHAwIwggH2BgorBgEEAdZ5AgQCBIIB5gSCAeIB4AB2AEiw42vapkc0D+VqAvqd\n" + - "MOscUgHLVt0sgdm7v6s52IRzAAABhqGDiCYAAAQDAEcwRQIgd7uqvHdSTSXqNPWs\n" + - "OQeCeT2vuKY3vj8jRcoJ9IIohqgCIQCtQfZ0lfZ1Y1GmwCTDc5NM++5mgp+ZpNWu\n" + - "F9OKsWoCPQB2AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABhqGD\n" + - "iJYAAAQDAEcwRQIgIHKa+XeYyDURUq9AVYEntGS5oJitKyWZjSOlpD+udZgCIQC/\n" + - "oVPtjJpcXP4OScYFsNWMPKUtZOO5mY5y7V65S84DrQB2ADtTd3U+LbmAToswWwb+\n" + - "QDtn2E/D9Me9AA0tcm/h+tQXAAABhqGDh8YAAAQDAEcwRQIgYT7aPr9YCtF5TCTp\n" + - "NICK9c5eiL6Ku/y9wM6ARgG2k1UCIQDomqlwGur+AMI4YIc1SNqyNVCyxgP1DxXP\n" + - "FYkX6BX17gB2AO7N0GTV2xrOxVy3nbTNE6Iyh0Z8vOzew1FIWUZxH7WbAAABhqGD\n" + - "iKkAAAQDAEcwRQIhAKTMliyTn48vvP9hN8jucD6rGZwRCqQI6suE6ADpN7bNAiB3\n" + - "zFZFdH8eJRn3RXjD/mzbmF201sNLitp9SOYAazubljANBgkqhkiG9w0BAQsFAAOC\n" + - "AQEAOOtzqtRFvxlJro61O0dEkDottToFh88vib3N3AofS5uW0nDpoS0L27XR8IDd\n" + - "2NfN+2XKAQXdz2BqHnjW1nAMXUx4TAMi4jG8XpOkvpSDXbjghD5EB10FyAzCuGmv\n" + - "mKxkVOU1DzL0kSLLQjLaJ57WUYsoE97f5O6rY9jlJpid32o1WgM1oZsBjPhO8Kiy\n" + - "KJ5zZHppolGPtuFYMUcatiqv//pH/5piwtlYSkbwMj5nYidSrSBciBzO53HFk1pE\n" + - "TABXFcoK3gmhWM04lysmJMwAzRUbNQVizpGDICbRjCOVnwCbutnSnka8pDHkq4Zy\n" + - "BrUeZe2xJe8jWvukwqvNzIIvwg==\n" + - "-----END CERTIFICATE-----"; - - // Owner: OID.2.5.4.17=100, STREET="10F.,NO.85,Yanping S. Rd.,Taipei City 100,Taiwan (R.O.C)", - // SERIALNUMBER=70759028, OID.1.3.6.1.4.1.311.60.2.1.3=TW, OID.1.3.6.1.4.1.311.60.2.1.2=Taiwan, - // OID.1.3.6.1.4.1.311.60.2.1.1=Taipei, OID.2.5.4.15=Private Organization, - // CN=evssldemo7.twca.com.tw, O=TAIWAN-CA INC., L=Taipei, ST=Taiwan, C=TW - // Issuer: CN=TWCA Global EVSSL Certification Authority, OU=Global EVSSL Sub-CA, - // O=TAIWAN-CA, C=TW - // Serial number: 47e70000001258f036a5b513091ccb2e - // Valid from: Tue Feb 07 02:03:08 PST 2023 until: Thu Mar 07 07:59:59 PST 2024 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIHdjCCBl6gAwIBAgIQR+cAAAASWPA2pbUTCRzLLjANBgkqhkiG9w0BAQsFADBz\n" + - "MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRwwGgYDVQQLExNHbG9i\n" + - "YWwgRVZTU0wgU3ViLUNBMTIwMAYDVQQDEylUV0NBIEdsb2JhbCBFVlNTTCBDZXJ0\n" + - "aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0yMzAyMDcxMDAzMDhaFw0yNDAzMDcxNTU5\n" + - "NTlaMIIBMzELMAkGA1UEBhMCVFcxDzANBgNVBAgTBlRhaXdhbjEPMA0GA1UEBxMG\n" + - "VGFpcGVpMRcwFQYDVQQKEw5UQUlXQU4tQ0EgSU5DLjEfMB0GA1UEAxMWZXZzc2xk\n" + - "ZW1vNy50d2NhLmNvbS50dzEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + - "FzAVBgsrBgEEAYI3PAIBARMGVGFpcGVpMRcwFQYLKwYBBAGCNzwCAQITBlRhaXdh\n" + - "bjETMBEGCysGAQQBgjc8AgEDEwJUVzERMA8GA1UEBRMINzA3NTkwMjgxQTA/BgNV\n" + - "BAkTODEwRi4sTk8uODUsWWFucGluZyBTLiBSZC4sVGFpcGVpIENpdHkgMTAwLFRh\n" + - "aXdhbiAoUi5PLkMpMQwwCgYDVQQREwMxMDAwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" + - "DwAwggEKAoIBAQDSX3co7XUdwxv8OEj7Mipq0Ot+1w+VYTFlPvdnryrv9st7ERLb\n" + - "+xJPJo7swgqbHeHKWlwYu4lkzJq6s3nAOkuYIP/O3uVmGDiilLSAVkukz9MooyjB\n" + - "466eArXY1VT9vpXVNmSLunAp5RU8H+2WWOUMmtJx/oYojqEbtWqnltlErvEjb2TM\n" + - "vR16d/vXI6QtMc+IV3nZ0SVdetH2E7ZvpP5mZqVSHNnOnVjqdd69hAJ4SJgG9lCM\n" + - "87ysm6UaJxQbEGxc6YkwrUNVet1tx2hBWltTyRw3oOBCBUwrPUTx7/pFh7yhci6p\n" + - "AhHp1j0OzAmZHOFTM+qO1L1vlmguO8zW0zWtAgMBAAGjggNCMIIDPjAfBgNVHSME\n" + - "GDAWgBRuvaErzuTC1Sh0XL3ZjG8EcioG3jAdBgNVHQ4EFgQUvvbgZHRNPdmGlxQS\n" + - "fcTzM2A14EkwUwYDVR0fBEwwSjBIoEagRIZCaHR0cDovL3NzbHNlcnZlci50d2Nh\n" + - "LmNvbS50dy9zc2xzZXJ2ZXIvR2xvYmFsRVZTU0xfUmV2b2tlXzIwMTIuY3JsMCEG\n" + - "A1UdEQQaMBiCFmV2c3NsZGVtbzcudHdjYS5jb20udHcwfwYIKwYBBQUHAQEEczBx\n" + - "MEQGCCsGAQUFBzAChjhodHRwOi8vc3Nsc2VydmVyLnR3Y2EuY29tLnR3L2NhY2Vy\n" + - "dC9HbG9iYWxFdnNzbF8yMDEyLnA3YjApBggrBgEFBQcwAYYdaHR0cDovL2V2c3Ns\n" + - "b2NzcC50d2NhLmNvbS50dy8wSAYDVR0gBEEwPzA0BgwrBgEEAYK/JQEBFgMwJDAi\n" + - "BggrBgEFBQcCARYWaHR0cDovL3d3dy50d2NhLmNvbS50dzAHBgVngQwBATAJBgNV\n" + - "HRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" + - "BQUHAwIwggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB2AFWB1MIWkDYBSuoLm1c8\n" + - "U/DA5Dh4cCUIFy+jqh0HE9MMAAABhitUR1YAAAQDAEcwRQIhANv7DhQm67R1Ilmg\n" + - "k5StrFQ1dqyELzZTAT3on84g0G/vAiAttP+EWWmztK2luQ7SxvQsmExDh/qGiZHq\n" + - "NAd2a8dUIgB1AO7N0GTV2xrOxVy3nbTNE6Iyh0Z8vOzew1FIWUZxH7WbAAABhitU\n" + - "RycAAAQDAEYwRAIgcU5n4DJaGWvTr3wZug59ItynMgCZ5z0ZVrZr2KwV70wCIHEv\n" + - "DAwNBLGsdj5IX/4E5hnzJvS7WroSLnRB6OW931JbAHYAdv+IPwq2+5VRwmHM9Ye6\n" + - "NLSkzbsp3GhCCp/mZ0xaOnQAAAGGK1RKDwAABAMARzBFAiBvlIvOnE8PhYJQueMh\n" + - "AOCwgREvnAsk3Edt59lcuqPrrQIhAOSRb3UmBYkHQ6k5pUJva0Mgk0GmnLR0de0s\n" + - "VxW3TTASMA0GCSqGSIb3DQEBCwUAA4IBAQAQB7oaouXBI6VpLzL+kzOZXSTbSClv\n" + - "LS33DTEBI3A8LTXHbFq6c4/ZdqieUzy42Kd0i9e3hI1hwQYPgEwxpROOcldX72r0\n" + - "EUTh0L+XrxN3YEgod6aCsjIiJlWYy6J2ZXVURnk/iWYAwYLa0JmmBGuWFjEnq4lO\n" + - "xL1C3M2mYAEC+Beb7Xyq1rcu97p4P8igJYM+VfwXNwYYRCXUr9f4ESD7t5vXlYoE\n" + - "c4m5KiBQD9XtZS77QRon9JCQklxTvMkxuLwWvSdzicEUzWeFp+kN/fcXL2SVsb17\n" + - "xDPMMsMMh7L/f+uMWDYZ+wH17LYQxOLi7VXT3fv8nl2X2iD3d4CCh0Tu\n" + - "-----END CERTIFICATE-----"; - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Thu Mar 23 17:30:19 PDT 2023", System.out); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TeliaSoneraCA.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TeliaSoneraCA.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TeliaSoneraCA.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/TeliaSoneraCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -/* - * Copyright (c) 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 8210432 - * @summary Interoperability tests with TeliaSonera Root CA v1 - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath TeliaSoneraCA OCSP - * @run main/othervm -Djava.security.debug=certpath TeliaSoneraCA CRL - */ - -/* - * Obtain TLS test artifacts for TeliaSonera Root CA v1 from: - * - * Valid TLS Certificates: - * https://juolukka.cover.sonera.net:10443/ - * - * Revoked TLS Certificates: - * https://juolukka.cover.sonera.net:10444/ - */ -public class TeliaSoneraCA { - - // Owner: CN=TeliaSonera Server CA v2, O=TeliaSonera, C=FI - // Issuer: CN=TeliaSonera Root CA v1, O=TeliaSonera - private static final String INT = "-----BEGIN CERTIFICATE-----\n" - + "MIIHHjCCBQagAwIBAgIQTEYq9tv794BPhMF8/qlytjANBgkqhkiG9w0BAQsFADA3\n" - + "MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9v\n" - + "dCBDQSB2MTAeFw0xNDEwMTYwODA5NTdaFw0zMjEwMTYwNTA0MDBaMEYxCzAJBgNV\n" - + "BAYTAkZJMRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEhMB8GA1UEAwwYVGVsaWFTb25l\n" - + "cmEgU2VydmVyIENBIHYyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA\n" - + "rwQN5rfRLbVAiYWLJF9SI4YLm8oqrtf8OjGybgoLyiMIo8nhY/atuGRFWCQNOnUK\n" - + "caZn29C360PlC5yYrsrSHuouROisqHSJcgA7HvV+37Rcry7daeDj6rfyx4yI5dmj\n" - + "LwHkK0j1NzhX1JxFDgPeLNuebgzv/j8OfRhYK/BttpystC4Zgm3gZheKDjYsDS5D\n" - + "gjffuOysP3vewrcuw0EIZFx+HawuwNBLq4tMf4VSitYDHJSLIM2TeXZGGY5slTbT\n" - + "yLnrU5mIzG9WKqxyy7qHuFw1JtlAXkCLmUEVaF9M+dRPiGIjlDrpBgbDD9mT2CSk\n" - + "V/XG1696/voY5xB8KNIC1cOSmSO7kdJyR5tWiDIJiwMXrTwG+kZiqlbcKDsZeJ9p\n" - + "5bZxXO0pEpde3wgEYRvFr5Cx4vcz4h5pom9coJOCW9tqXU43KcueTrt4Ks9f92q1\n" - + "ehjyEnCh0BCdrjUOXsUtFosm9qxJnDwVlThYhS9EHuCTNBgj1Yxj6A+8fwwJP9DN\n" - + "CbWQx5afT+h+9FNDNRC/nEcesP1Yh9s15Se270pQW0CejUNziYG7Dft7T+PVH/fU\n" - + "zaWU8g0tJjtuQgiCWVqw4WkUmYY2S0R89zAotcpz2mvNO8ma2iJbubHi3c0ULfHH\n" - + "nkWKsdpzZmK4N0Wi6/V5yWdmL5RFkFecL8r7+9OtCB0CAwEAAaOCAhUwggIRMIGK\n" - + "BggrBgEFBQcBAQR+MHwwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnRydXN0LnRl\n" - + "bGlhc29uZXJhLmNvbTBLBggrBgEFBQcwAoY/aHR0cDovL3JlcG9zaXRvcnkudHJ1\n" - + "c3QudGVsaWFzb25lcmEuY29tL3RlbGlhc29uZXJhcm9vdGNhdjEuY2VyMBIGA1Ud\n" - + "EwEB/wQIMAYBAf8CAQAwVQYDVR0gBE4wTDBKBgwrBgEEAYIPAgMBAQIwOjA4Bggr\n" - + "BgEFBQcCARYsaHR0cHM6Ly9yZXBvc2l0b3J5LnRydXN0LnRlbGlhc29uZXJhLmNv\n" - + "bS9DUFMwDgYDVR0PAQH/BAQDAgEGMIHGBgNVHR8Egb4wgbswQKA+oDyGOmh0dHA6\n" - + "Ly9jcmwtMy50cnVzdC50ZWxpYXNvbmVyYS5jb20vdGVsaWFzb25lcmFyb290Y2F2\n" - + "MS5jcmwwd6B1oHOGcWxkYXA6Ly9jcmwtMS50cnVzdC50ZWxpYXNvbmVyYS5jb20v\n" - + "Y249VGVsaWFTb25lcmElMjBSb290JTIwQ0ElMjB2MSxvPVRlbGlhU29uZXJhP2Nl\n" - + "cnRpZmljYXRlcmV2b2NhdGlvbmxpc3Q7YmluYXJ5MB0GA1UdDgQWBBQvSTwpT9cH\n" - + "JfnGjNVk9WY9EoMilTAfBgNVHSMEGDAWgBTwj1k4ALP1j5qWDNXr+nuqF+gTEjAN\n" - + "BgkqhkiG9w0BAQsFAAOCAgEAg9EVFW6ioZ2ctrX8KqvW9XPYZR01yNgqlO7pwBWf\n" - + "HzuBCbUdyVzumfQnU24Sce92oMtEfyuxIOmhvoXU7LpnYlH3Q29UGP5dL0D3edGz\n" - + "HeU6Tf8bkcOEHtnTrkd+y+rfFSDWYl9r1y993NAcrBHhroQCE53mlrO7TjXa3zDq\n" - + "6LGR8T8VgvGw0IBz6mzAks0wMYB0b4uREPmWXi+m+RqG3lnpl+eBzz6YVLkxIYMq\n" - + "QIXJIBsu4/ybmadsfdql6E8Lo3dKVD4UG10mtd+iPbJiBiW/a9VbEe3NVKIv4H2y\n" - + "HqYcxDXAeUI66E3K2cjCmKoQaa0Ywt02ikZFd0v1OWNPS7YWbEJWkVR1PcPMESK9\n" - + "6HKI4xhG2tJesmXjQ8q8aSx2u79Zts3ewjKqTmurf6FXW3u9TpSCUe6Drr/3X7Ve\n" - + "nBy4M0sLwCecD/L9gjTa+EItQTYzCkpxiMO49tQdX/BpwgWju4Kg3qkaBNTzvSlk\n" - + "gdnRJqCUkVuzwK4yBqUoyRz3prlhvvRGdZJKf6IXRDhncpey5pm0PQYQ4cArx7Go\n" - + "AaAKz0ZTHOKjnM2KIdUhBJQybL7oPklSfkeMWoUoYED6R4YMTt/JXX4ixEb5DgDJ\n" - + "0F+bNcF7qGrJTkTx0Ccy4BuuY05hJckd72E7WdmjN7DDeosghgWZNV/6D7N5tfxo\n" - + "nlU=\n" - + "-----END CERTIFICATE-----"; - - // Owner: CN=juolukka.cover.sonera.net, OU=security, O=Telia Finland Oyj, L=helsinki, C=FI - // Issuer: CN=TeliaSonera Server CA v2, O=TeliaSonera, C=FI - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHiDCCBXCgAwIBAgIPAWOq14hk136UDQY3WSjLMA0GCSqGSIb3DQEBCwUAMEYx\n" + - "CzAJBgNVBAYTAkZJMRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEhMB8GA1UEAwwYVGVs\n" + - "aWFTb25lcmEgU2VydmVyIENBIHYyMB4XDTE4MDUyOTA3NDA0MVoXDTE5MDUyOTA3\n" + - "NDA0MVowczELMAkGA1UEBhMCRkkxETAPBgNVBAcMCGhlbHNpbmtpMRowGAYDVQQK\n" + - "DBFUZWxpYSBGaW5sYW5kIE95ajERMA8GA1UECwwIc2VjdXJpdHkxIjAgBgNVBAMM\n" + - "GWp1b2x1a2thLmNvdmVyLnNvbmVyYS5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" + - "DwAwggEKAoIBAQDLks9F8ZUqV9G4jn3fY234OX09Dmqqtuk0qAmjWpF0JAn2o64t\n" + - "whVxFLx9e2IwUPTQgyo6FwRsiT19m99BhgxYnJOxVRwURxSL3mqlV9gX4oFMmT4O\n" + - "EOYEjaJXi8ne1pJX80y2hVQ48XqgODnKdKZVwa5YoeWZQJiaq+C5JkMDN8qzpiyQ\n" + - "X3EfJspLkKy2E+UVxWmfnyf0v70ES9TQ8qgxwvsf7LRZ8Jixq7TTO5VbqWsdBvJC\n" + - "9Zm2aBOYJ7ptSZQ5YDfeUJG2c9S/zFmngoPnTrvAZwUeU3YTrbdZQy899ZOatWac\n" + - "6lHUYU2EagEmbj/jtIvJ6wMbzhleIXRQFWibAgMBAAGjggNEMIIDQDAfBgNVHSME\n" + - "GDAWgBQvSTwpT9cHJfnGjNVk9WY9EoMilTAdBgNVHQ4EFgQUbMozh4osL4gFJvb5\n" + - "baELpQSKEhIwDgYDVR0PAQH/BAQDAgSwME4GA1UdIARHMEUwQwYGZ4EMAQICMDkw\n" + - "NwYIKwYBBQUHAgEWK2h0dHA6Ly9yZXBvc2l0b3J5LnRydXN0LnRlbGlhc29uZXJh\n" + - "LmNvbS9DUFMwJAYDVR0RBB0wG4IZanVvbHVra2EuY292ZXIuc29uZXJhLm5ldDBN\n" + - "BgNVHR8ERjBEMEKgQKA+hjxodHRwOi8vY3JsLTMudHJ1c3QudGVsaWFzb25lcmEu\n" + - "Y29tL3RlbGlhc29uZXJhc2VydmVyY2F2Mi5jcmwwHQYDVR0lBBYwFAYIKwYBBQUH\n" + - "AwIGCCsGAQUFBwMBMIGGBggrBgEFBQcBAQR6MHgwJwYIKwYBBQUHMAGGG2h0dHA6\n" + - "Ly9vY3NwLnRydXN0LnRlbGlhLmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL3JlcG9z\n" + - "aXRvcnkudHJ1c3QudGVsaWFzb25lcmEuY29tL3RlbGlhc29uZXJhc2VydmVyY2F2\n" + - "Mi5jZXIwggF/BgorBgEEAdZ5AgQCBIIBbwSCAWsBaQB2AG9Tdqwx8DEZ2JkApFEV\n" + - "/3cVHBHZAsEAKQaNsgiaN9kTAAABY6rXpS0AAAQDAEcwRQIgfMLEFYxQcncL3am/\n" + - "W2x7DMZ1+Vh1tDLw/0qIQB40VBQCIQC1eyF8Q6CcQs+gIgzpy7OiZSosSlykyOgW\n" + - "qHkj/0UPygB3AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABY6rX\n" + - "pLEAAAQDAEgwRgIhAJxveFVsFrfttSJIxHsMPAvvevptaV2CxsGwubAi8wDDAiEA\n" + - "jNbbYfUiYtmQ5v4yc6T+GcixztNIlMzQ7OTK+u9zqSoAdgBVgdTCFpA2AUrqC5tX\n" + - "PFPwwOQ4eHAlCBcvo6odBxPTDAAAAWOq16YXAAAEAwBHMEUCIQCCkCL2zn/AoMVI\n" + - "BdsoJelUBLsAnQ+GlIafiyZYcCwhBAIgdsFM05eNmL5hfn3+WtfgmipwcK1qp7kO\n" + - "ONzO69aqrnEwDQYJKoZIhvcNAQELBQADggIBAIl5UWSwCXF85+2lU6t89K7I4TvZ\n" + - "Ggof0NLngea9qxBq00opfnl9i2LPRnsjh9s3iA29i2daTEuJn3qt3Ygcm27Jd7WM\n" + - "5StcxQ483GAaL5s5m2QqkZB8eLfez3tIyCMGCAyixBDNRNPVI4xZr6sSOenWtipo\n" + - "gMt+/gvRIMdMT79IXPFz4W9RWCwnfJNOlfH2OkS3KZYaPSaEvs6sfMW1DDZosrBy\n" + - "6F+DITPLllOVSE4+PTxvXLKVy+srFwF1VocQXKkWMHQ7AfWNnOGzb7B1qg7gsw0n\n" + - "axqinyCjkhMpHpcVtmD9Pi15HLFDIy9yI2S+FHJQfhUSmM/LdCWzQpnee6/Wo+uw\n" + - "p0Jg2v6v9GGaqfpuiVJPFN9dOv3OjMU7DL5lgMRWFRo2T8+wBHXDyBhT0W0y5kRJ\n" + - "eWA7t6CnkziHuaOihZAHUH3nn5exjqUFVS0ThbF6hxN7HAlq/xIbTKlZjkLlc14W\n" + - "fB8vkxJyy/tgBZ4dCj9Y1Y32d4eFT5JZJgqgkN59SmX56BswNXncGrk/vWZFFx+g\n" + - "9dgb8QSe8KseD1iSLc7SsqVDv8NPYdaI3eZ90W8Wv0/CDls321O6UbAmURzQwFGB\n" + - "w8WnteoVBi6Wf6M1TxIfJsXBYeIN0BB6AYc8cmZIOtx2C8aH4JJT45MyFnBv3ac5\n" + - "Ahs9pGn/+K+5yb2e\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=juolukka.cover.sonera.net, OU=Security, O=TeliaSonera Finland, L=Helsinki, C=FI - // Issuer: CN=TeliaSonera Server CA v2, O=TeliaSonera, C=FI - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGEDCCA/igAwIBAgIRAKWJTjs6v04ZTyb2wJxfnJswDQYJKoZIhvcNAQELBQAw\n" + - "RjELMAkGA1UEBhMCRkkxFDASBgNVBAoMC1RlbGlhU29uZXJhMSEwHwYDVQQDDBhU\n" + - "ZWxpYVNvbmVyYSBTZXJ2ZXIgQ0EgdjIwHhcNMTYxMjIzMDcwMTQ2WhcNMTkxMjIz\n" + - "MDcwMTQ2WjB1MQswCQYDVQQGEwJGSTERMA8GA1UEBwwISGVsc2lua2kxHDAaBgNV\n" + - "BAoME1RlbGlhU29uZXJhIEZpbmxhbmQxETAPBgNVBAsMCFNlY3VyaXR5MSIwIAYD\n" + - "VQQDDBlqdW9sdWtrYS5jb3Zlci5zb25lcmEubmV0MIIBIjANBgkqhkiG9w0BAQEF\n" + - "AAOCAQ8AMIIBCgKCAQEAt2u92TgTFdm1OEfmWFPe+ESBi+2ox4y1EDoin8RydMyO\n" + - "DI6+0HHnKfDZa1YViI5b6MLJKWIAyUszAg5hc0S3upElfSsBvUW6zuQTxMi2vTYE\n" + - "4tcqwIEyCUaiv4wC+DuO5CyGR32yR6HB/W5Ny200dPs2SO03ESEJ+LH4Tw5AI8JJ\n" + - "UZHW+lA+yUHnlc3q47svpbspjt0C/THyukd1hbXTBB0mPXqPux+ClvtZBWUJb7ti\n" + - "1cPfcCNd79KRObzcgxqcOIaUFz4LjjKezhzVSL7tJOANOHZ09qDeOAkk/X9POx4h\n" + - "a5XyWfH1zaQ0QlZ2mKBeHebCIJkgTZZVipagRVOgcwIDAQABo4IByDCCAcQwgY0G\n" + - "CCsGAQUFBwEBBIGAMH4wLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnRydXN0LnRl\n" + - "bGlhc29uZXJhLmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL3JlcG9zaXRvcnkudHJ1\n" + - "c3QudGVsaWFzb25lcmEuY29tL3RlbGlhc29uZXJhc2VydmVyY2F2Mi5jZXIwHwYD\n" + - "VR0jBBgwFoAUL0k8KU/XByX5xozVZPVmPRKDIpUwTgYDVR0gBEcwRTBDBgZngQwB\n" + - "AgIwOTA3BggrBgEFBQcCARYraHR0cDovL3JlcG9zaXRvcnkudHJ1c3QudGVsaWFz\n" + - "b25lcmEuY29tL0NQUzBNBgNVHR8ERjBEMEKgQKA+hjxodHRwOi8vY3JsLTMudHJ1\n" + - "c3QudGVsaWFzb25lcmEuY29tL3RlbGlhc29uZXJhc2VydmVyY2F2Mi5jcmwwHQYD\n" + - "VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB/wQEAwIEsDAkBgNV\n" + - "HREEHTAbghlqdW9sdWtrYS5jb3Zlci5zb25lcmEubmV0MB0GA1UdDgQWBBSa+vJH\n" + - "I6Lt9Aqw5ondhoZu4/IJezANBgkqhkiG9w0BAQsFAAOCAgEASRK1l1MZb/IRlyi+\n" + - "XjfZcxJdFuNzW2kpZstW6Ni2XiD3p7aROBfDFtu7GajzZHb6p76auDb4NwJgeE/3\n" + - "6gnXoIK00HwpF2RAhxDpkF8r3q0jSqGhSv/xz9Nx7JBzgqfSw3Ha4ohioIed3uc+\n" + - "nMDyvVenio4GYgtxIIubSybCxMv/lBA/S4daIVCYK3VOoBbM2F36ecAKvRU5vIWM\n" + - "urXsfANL3u4qgJpaM0DclzFsOkVsRPffzToko/Nr6pGXYjt47IzTRlwLMnLehoZW\n" + - "ZZMGMVVOlR7XGf81UjWB6OsKeoQ4FWgcb/rIJcZusm+LqvnsCHuC3gtuC2nGA7lr\n" + - "fseUlG7QZN9/QfUIyvL69wAzeVj1cUcd7GHcAH9DyZJfI8orv4PyUvitDdgISkFu\n" + - "GZ562O7cGmCv00/6I4t0z9wZal8a5lRDoKXAYy+u/adrO1JjLwi11y/DTw9LQ7sJ\n" + - "gVP/v2GsI0ajF9A6z33UHN9uxXZVmQNvOiMkcJiGLovFgu5zxoAg2W3pHjbBbeL8\n" + - "v5MPqgsKafgzaSRtXBBvaISHi9hhRR8v/qSwO3NyLm8uAhQD4x+OPHrmQ/s16j45\n" + - "Ib53UHj1k6byXGUqDgzFBsmEPV6Shf2C4/HcRHpAX8wQx3xVwDtRzDpNUR6vnNfi\n" + - "PwzRU1xsQKd8llmgl4l+fYV0tBA=\n" + - "-----END CERTIFICATE-----"; - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator.enableCRLCheck(); - } else { - // OCSP check by default - pathValidator.enableOCSPCheck(); - } - - // Validate valid - pathValidator.validate(new String[]{VALID, INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, - ValidatePathWithParams.Status.REVOKED, - "Thu Dec 22 23:14:55 PST 2016", System.out); - - // reset validation date back to current date - pathValidator.resetValidationDate(); - } -} diff -Nru openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ValidatePathWithURL.java openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ValidatePathWithURL.java --- openjdk-21-21.0.1+12/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ValidatePathWithURL.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ValidatePathWithURL.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,229 @@ +/* + * 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 jtreg.SkippedException; + +import javax.net.ssl.*; +import javax.security.auth.x500.X500Principal; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.security.*; +import java.security.cert.*; +import java.security.cert.Certificate; + +public class ValidatePathWithURL { + + private final X509Certificate rootCertificate; + private final X500Principal rootPrincipal; + + /** + * Enables the certificate revocation checking and loads the certificate from + * cacerts file for give caAlias + * + * @param caAlias CA alias for CA certificate in cacerts file + * @throws Exception when fails to get CA certificate from cacerts file + */ + public ValidatePathWithURL(String caAlias) throws Exception { + System.setProperty("com.sun.net.ssl.checkRevocation", "true"); + Security.setProperty("ssl.TrustManagerFactory.algorithm", "SunPKIX"); + + // some test sites don't have correct hostname specified in test certificate + HttpsURLConnection.setDefaultHostnameVerifier(new CustomHostnameVerifier()); + + String FS = System.getProperty("file.separator"); + String CACERTS_STORE = + System.getProperty("test.jdk") + FS + "lib" + FS + "security" + FS + "cacerts"; + + KeyStore cacerts = KeyStore.getInstance("PKCS12"); + try (FileInputStream fis = new FileInputStream(CACERTS_STORE)) { + cacerts.load(fis, null); + } + + rootCertificate = (X509Certificate) cacerts.getCertificate(caAlias); + rootPrincipal = rootCertificate.getSubjectX500Principal(); + } + + /** + * Enable revocation checking using OCSP and disables CRL check + */ + public static void enableOCSPOnly() { + System.setProperty("com.sun.security.enableCRLDP", "false"); + Security.setProperty("ocsp.enable", "true"); + } + + /** + * Enable revocation checking using CRL + */ + public static void enableCRLOnly() { + System.setProperty("com.sun.security.enableCRLDP", "true"); + Security.setProperty("ocsp.enable", "false"); + } + + /** + * Enable revocation checking using OCSP or CRL + */ + public static void enableOCSPAndCRL() { + System.setProperty("com.sun.security.enableCRLDP", "true"); + Security.setProperty("ocsp.enable", "true"); + } + + /** + * Logs revocation settings + */ + public static void logRevocationSettings() { + System.out.println("====================================================="); + System.out.println("CONFIGURATION"); + System.out.println("====================================================="); + System.out.println("http.proxyHost :" + System.getProperty("http.proxyHost")); + System.out.println("http.proxyPort :" + System.getProperty("http.proxyPort")); + System.out.println("https.proxyHost :" + System.getProperty("https.proxyHost")); + System.out.println("https.proxyPort :" + System.getProperty("https.proxyPort")); + System.out.println("https.socksProxyHost :" + + System.getProperty("https.socksProxyHost")); + System.out.println("https.socksProxyPort :" + + System.getProperty("https.socksProxyPort")); + System.out.println("jdk.certpath.disabledAlgorithms :" + + Security.getProperty("jdk.certpath.disabledAlgorithms")); + System.out.println("com.sun.security.enableCRLDP :" + + System.getProperty("com.sun.security.enableCRLDP")); + System.out.println("ocsp.enable :" + Security.getProperty("ocsp.enable")); + System.out.println("====================================================="); + } + + /** + * Validates end entity certificate used in provided test URL using + * HttpsURLConnection. Validation is skipped on network error or if + * the certificate is expired. + * + * @param testURL URL to validate + * @param revokedCert if true then validate is REVOKED certificate + * @throws Exception on failure to validate certificate + */ + public void validateDomain(final String testURL, + final boolean revokedCert) + throws Exception { + System.out.println(); + System.out.println("===== Validate " + testURL + "====="); + if (!validateDomainCertChain(testURL, revokedCert)) { + throw new RuntimeException("Failed to validate " + testURL); + } + System.out.println("======> SUCCESS"); + } + + private boolean validateDomainCertChain(final String testURL, + final boolean revokedCert) + throws Exception { + HttpsURLConnection httpsURLConnection = null; + try { + URL url = new URL(testURL); + httpsURLConnection = (HttpsURLConnection) url.openConnection(); + httpsURLConnection.setInstanceFollowRedirects(false); + httpsURLConnection.connect(); + + // certain that test certificate anchors to trusted CA for VALID certificate + // if the connection is successful + Certificate[] chain = httpsURLConnection.getServerCertificates(); + httpsURLConnection.disconnect(); + validateAnchor(chain); + } catch (SSLHandshakeException e) { + System.out.println("SSLHandshakeException: " + e.getMessage()); + Throwable cause = e.getCause(); + + while (cause != null) { + if (cause instanceof CertPathValidatorException cpve) { + if (cpve.getReason() == CertPathValidatorException.BasicReason.REVOKED + || cpve.getCause() instanceof CertificateRevokedException) { + System.out.println("Certificate is revoked"); + + // We can validate anchor for revoked certificates as well + Certificate[] chain = cpve.getCertPath().getCertificates().toArray(new Certificate[0]); + validateAnchor(chain); + + if (revokedCert) { + return true; + } + } else if (cpve.getReason() == CertPathValidatorException.BasicReason.EXPIRED + || cpve.getCause() instanceof CertificateExpiredException) { + System.out.println("Certificate is expired"); + throw new SkippedException("Certificate is expired, skip the test"); + } + break; + } + cause = cause.getCause(); + } + + throw new RuntimeException("Unhandled exception", e); + } catch (SSLException e) { + // thrown if root CA is not included in cacerts + throw new RuntimeException(e); + } catch (IOException e) { + throw new SkippedException("Network setup issue, skip this test", e); + } finally { + if (httpsURLConnection != null) { + httpsURLConnection.disconnect(); + } + } + + return !revokedCert; + } + + private void validateAnchor(Certificate[] chain) throws Exception { + X509Certificate interCert = null; + + // fail if there is no intermediate CA or self-signed + if (chain.length < 2) { + throw new RuntimeException("Cert chain too short " + chain.length); + } else { + System.out.println("Finding intermediate certificate issued by CA"); + for (Certificate cert : chain) { + if (cert instanceof X509Certificate certificate) { + System.out.println("Checking: " + certificate.getSubjectX500Principal()); + System.out.println("Issuer: " + certificate.getIssuerX500Principal()); + if (certificate.getIssuerX500Principal().equals(rootPrincipal)) { + interCert = certificate; + break; + } + } + } + } + + if (interCert == null) { + throw new RuntimeException("Intermediate Root CA not found in the chain"); + } + + // validate intermediate CA signed by root CA under test + System.out.println("Found intermediate root CA: " + interCert.getSubjectX500Principal()); + System.out.println("intermediate CA Issuer: " + interCert.getIssuerX500Principal()); + interCert.verify(rootCertificate.getPublicKey()); + System.out.println("Verified: Intermediate CA signed by test root CA"); + } + + private static class CustomHostnameVerifier implements HostnameVerifier { + @Override + public boolean verify(String hostname, SSLSession session) { + // Allow any hostname + return true; + } + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java openjdk-21-21.0.2+13/test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java --- openjdk-21-21.0.1+12/test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * 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; + +/** + * @test + * @bug 8312191 + * @summary Standard color spaces should be reused for CompatibleDestImage + */ +public final class CompatibleColorSpace { + + private static final int[] spaces = { + ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB, + ColorSpace.CS_PYCC, ColorSpace.CS_sRGB + }; + + public static void main(String[] args) { + for (int from : spaces) { + for (int to : spaces) { + test(from, to); + } + } + } + + private static void test(int from, int to) { + ColorSpace srcCS = ColorSpace.getInstance(from); + ColorSpace dstCS = ColorSpace.getInstance(to); + ColorConvertOp op = new ColorConvertOp(srcCS, dstCS, null); + BufferedImage src = new BufferedImage(10, 10, + BufferedImage.TYPE_INT_ARGB); + BufferedImage dst = op.filter(src, null); + // dst image is not set and will be created automatically, the dstCS + // should be reused + if (dst.getColorModel().getColorSpace() != dstCS) { + throw new RuntimeException("Wrong color space"); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/java2d/marlin/TestCreateStrokedShapeJoins.java openjdk-21-21.0.2+13/test/jdk/sun/java2d/marlin/TestCreateStrokedShapeJoins.java --- openjdk-21-21.0.1+12/test/jdk/sun/java2d/marlin/TestCreateStrokedShapeJoins.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/java2d/marlin/TestCreateStrokedShapeJoins.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * 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.awt.*; +import java.awt.image.*; +import java.awt.geom.*; +import java.util.Arrays; +import javax.imageio.*; + +/** + * @test + * @bug 8316741 + * @summary Verifies that Marlin renderer's Stroker generates properly joins + * in createStrokedShape() + * @run main TestCreateStrokedShapeJoins + */ +public class TestCreateStrokedShapeJoins { + + static final boolean SAVE_IMAGE = false; + + private final static int W = 200; + + private final static int[] REF_COUNTS = new int[] {4561, 4790, 5499}; + + public static void main(String[] args) throws Exception { + final int[] test = new int[] { + test(BasicStroke.JOIN_BEVEL), + test(BasicStroke.JOIN_ROUND), + test(BasicStroke.JOIN_MITER) + }; + + System.out.println("test: " + Arrays.toString(test)); + System.out.println("ref: " + Arrays.toString(REF_COUNTS)); + + // check results: + for (int i = 0; i < REF_COUNTS.length; i++) { + if (test[i] != REF_COUNTS[i]) { + throw new RuntimeException("Invalid test[" + i + "]: " + test[i] + " != " + REF_COUNTS[i]); + } + } + } + + private static int test(int join) throws Exception { + final BufferedImage image = new BufferedImage(W, W, BufferedImage.TYPE_INT_ARGB); + final Graphics2D g = image.createGraphics(); + try { + g.setPaint(Color.BLACK); + g.fillRect(0, 0, W, W); + g.setPaint(Color.WHITE); + g.setTransform(new AffineTransform(W, 0, 0, W, 0, 0)); + + final BasicStroke stroke = new BasicStroke(0.15f, 0, join, 10); + + final Path2D p = new Path2D.Float(); + p.moveTo(0.95f, 0.6f); + p.lineTo(0.5f, 0.5f); + p.lineTo(0.95f, 0.4f); + + final Shape outline = stroke.createStrokedShape(p); + g.fill(outline); + } finally { + g.dispose(); + } + if (SAVE_IMAGE) { + final File file = new File("TestCreateStrokedShapeJoins-" + join + ".png"); + System.out.println("Writing " + file.getAbsolutePath()); + ImageIO.write(image, "png", file); + } + int count = 0; + + for (int y = 0; y < W; y++) { + for (int x = 0; x < W; x++) { + final int rgb = image.getRGB(x, y); + final int b = rgb & 0xFF; + + if (b != 0) { + count++; + } + } + } + return count; + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java openjdk-21-21.0.2+13/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java 2024-01-16 16:19:00.000000000 +0000 @@ -28,7 +28,7 @@ * 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136 * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 - * 8305975 8304760 8307134 8295894 8314960 + * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -47,12 +47,12 @@ + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 97; + private static final int COUNT = 106; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "35:5B:BF:02:F8:3E:34:0D:72:01:6C:EB:10:90:CA:A1:DD:B5:01:EF:D8:0C:5B:26:F5:EF:C5:C5:4B:9D:61:3E"; + = "C6:81:90:32:46:65:82:69:6B:BF:EE:C2:BE:AB:48:59:CB:2F:B6:7B:93:F2:B3:7E:A0:07:17:0C:79:F6:D9:AC"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -147,6 +147,8 @@ "5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE"); put("letsencryptisrgx1 [jdk]", "96:BC:EC:06:26:49:76:F3:74:60:77:9A:CF:28:C5:A7:CF:E8:A3:C0:AA:E1:1A:8F:FC:EE:05:C0:BD:DF:08:C6"); + put("letsencryptisrgx2 [jdk]", + "69:72:9B:8E:15:A8:6E:FC:17:7A:57:AF:B7:17:1D:FC:64:AD:D2:8C:2F:CA:8C:F1:50:7E:34:45:3C:CB:14:70"); put("luxtrustglobalrootca [jdk]", "A1:B2:DB:EB:64:E7:06:C6:16:9E:3C:41:18:B2:3B:AA:09:01:8A:84:27:66:6D:8B:F0:E2:88:91:EC:05:19:50"); put("quovadisrootca [jdk]", @@ -161,6 +163,14 @@ "18:F1:FC:7F:20:5D:F8:AD:DD:EB:7F:E0:07:DD:57:E3:AF:37:5A:9C:4D:8D:73:54:6B:F4:F1:FE:D1:E1:8D:35"); put("quovadisrootca3g3 [jdk]", "88:EF:81:DE:20:2E:B0:18:45:2E:43:F8:64:72:5C:EA:5F:BD:1F:C2:D9:D2:05:73:07:09:C5:D8:B8:69:0F:46"); + put("digicertcseccrootg5 [jdk]", + "26:C5:6A:D2:20:8D:1E:9B:15:2F:66:85:3B:F4:79:7C:BE:B7:55:2C:1F:3F:47:72:51:E8:CB:1A:E7:E7:97:BF"); + put("digicertcsrsarootg5 [jdk]", + "73:53:B6:D6:C2:D6:DA:42:47:77:3F:3F:07:D0:75:DE:CB:51:34:21:2B:EA:D0:92:8E:F1:F4:61:15:26:09:41"); + put("digicerttlseccrootg5 [jdk]", + "01:8E:13:F0:77:25:32:CF:80:9B:D1:B1:72:81:86:72:83:FC:48:C6:E1:3B:E9:C6:98:12:85:4A:49:0C:1B:05"); + put("digicerttlsrsarootg5 [jdk]", + "37:1A:00:DC:05:33:B3:72:1A:7E:EB:40:E8:41:9E:70:79:9D:2B:0A:0F:2C:1D:80:69:31:65:F7:CE:C4:AD:75"); put("secomscrootca2 [jdk]", "51:3B:2C:EC:B8:10:D4:CD:E5:DD:85:39:1A:DF:C6:C2:DD:60:D8:7B:B7:36:D2:B5:21:48:4A:A4:7A:0E:BE:F6"); put("swisssigngoldg2ca [jdk]", @@ -255,6 +265,14 @@ "34:9D:FA:40:58:C5:E2:63:12:3B:39:8A:E7:95:57:3C:4E:13:13:C8:3F:E6:8F:93:55:6C:D5:E8:03:1B:3C:7D"); put("certignarootca [jdk]", "D4:8D:3D:23:EE:DB:50:A4:59:E5:51:97:60:1C:27:77:4B:9D:7B:18:C9:4D:5A:05:95:11:A1:02:50:B9:31:68"); + put("teliarootcav2 [jdk]", + "24:2B:69:74:2F:CB:1E:5B:2A:BF:98:89:8B:94:57:21:87:54:4E:5B:4D:99:11:78:65:73:62:1F:6A:74:B8:2C"); + put("emsignrootcag1 [jdk]", + "40:F6:AF:03:46:A9:9A:A1:CD:1D:55:5A:4E:9C:CE:62:C7:F9:63:46:03:EE:40:66:15:83:3D:C8:C8:D0:03:67"); + put("emsigneccrootcag3 [jdk]", + "86:A1:EC:BA:08:9C:4A:8D:3B:BE:27:34:C6:12:BA:34:1D:81:3E:04:3C:F9:E8:A8:62:CD:5C:57:A3:6B:BE:6B"); + put("emsignrootcag2 [jdk]", + "1A:A0:C2:70:9E:83:1B:D6:E3:B5:12:9A:00:BA:41:F7:EE:EF:02:08:72:F1:E6:50:4B:F0:F6:C3:F2:4F:3A:F3"); } }; diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/Basic.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/Basic.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/Basic.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/Basic.java 2024-01-16 16:19:00.000000000 +0000 @@ -58,6 +58,8 @@ import com.sun.security.auth.module.*; import com.sun.security.auth.callback.*; +import jtreg.SkippedException; +import org.testng.SkipException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -113,7 +115,11 @@ @Test public void testBasic() throws Exception { String[] args = {"sm", "Basic.policy"}; - main(new Basic(), args); + try { + main(new Basic(), args); + } catch (SkippedException se) { + throw new SkipException("One or more tests are skipped"); + } } private static class FooEntry implements KeyStore.Entry { } diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/CertChainRemoval.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/CertChainRemoval.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/CertChainRemoval.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/CertChainRemoval.java 2024-01-16 16:19:00.000000000 +0000 @@ -38,6 +38,8 @@ import java.security.Provider; import java.security.cert.Certificate; +import jtreg.SkippedException; +import org.testng.SkipException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -74,7 +76,11 @@ @Test public void test() throws Exception { - main(new CertChainRemoval()); + try { + main(new CertChainRemoval()); + } catch (SkippedException se) { + throw new SkipException("One or more tests are skipped"); + } } private static void printKeyStore(String header, KeyStore ks) diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -29,6 +29,8 @@ * @run testng/othervm ClientAuth */ +import jtreg.SkippedException; +import org.testng.SkipException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -119,7 +121,11 @@ private void runTest(String[] args) throws Exception { System.out.println("Running with args: " + Arrays.toString(args)); parseArguments(args); - main(new ClientAuth()); + try { + main(new ClientAuth()); + } catch (SkippedException se) { + throw new SkipException("One or more tests are skipped"); + } } /* diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, 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 @@ -26,6 +26,8 @@ * @library /test/lib .. * @run testng/othervm SecretKeysBasic */ +import jtreg.SkippedException; +import org.testng.SkipException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -62,7 +64,11 @@ @Test public void testBasic() throws Exception { - main(new SecretKeysBasic()); + try { + main(new SecretKeysBasic()); + } catch (SkippedException se) { + throw new SkipException("One or more tests are skipped"); + } } public void main(Provider p) throws Exception { diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/PKCS11Test.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/PKCS11Test.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/PKCS11Test.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/PKCS11Test.java 2024-01-16 16:19:00.000000000 +0000 @@ -62,27 +62,38 @@ import jdk.test.lib.artifacts.Artifact; import jdk.test.lib.artifacts.ArtifactResolver; import jdk.test.lib.artifacts.ArtifactResolverException; +import jtreg.SkippedException; public abstract class PKCS11Test { - private boolean enableSM = false; - static final Properties props = System.getProperties(); - static final String PKCS11 = "PKCS11"; - // directory of the test source static final String BASE = System.getProperty("test.src", "."); - static final String TEST_CLASSES = System.getProperty("test.classes", "."); - static final char SEP = File.separatorChar; - - private static final String DEFAULT_POLICY = - BASE + SEP + ".." + SEP + "policy"; - // directory corresponding to BASE in the /closed hierarchy static final String CLOSED_BASE; + private static final String DEFAULT_POLICY = BASE + SEP + ".." + SEP + "policy"; + private static final String PKCS11_REL_PATH = "sun/security/pkcs11"; + private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray(); + private static final SecureRandom srdm = new SecureRandom(); + + static double nss_version = -1; + static ECCState nss_ecc_status = ECCState.Basic; + + // The NSS library we need to search for in getNSSLibDir() + // Default is "libsoftokn3.so", listed as "softokn3" + // The other is "libnss3.so", listed as "nss3". + static String nss_library = "softokn3"; + + // NSS versions of each library. It is simpler to keep nss_version + // for quick checking for generic testing than many if-else statements. + static double softoken3_version = -1; + static double nss3_version = -1; + static Provider pkcs11 = newPKCS11Provider(); + private static String PKCS11_BASE; + private static Map osMap; static { // hack @@ -97,24 +108,18 @@ System.setProperty("closed.base", CLOSED_BASE); } - // NSS version info - public static enum ECCState { None, Basic, Extended }; - static double nss_version = -1; - static ECCState nss_ecc_status = ECCState.Basic; - - // The NSS library we need to search for in getNSSLibDir() - // Default is "libsoftokn3.so", listed as "softokn3" - // The other is "libnss3.so", listed as "nss3". - static String nss_library = "softokn3"; + static { + try { + PKCS11_BASE = getBase(); + } catch (Exception e) { + // ignore + } + } - // NSS versions of each library. It is simplier to keep nss_version - // for quick checking for generic testing than many if-else statements. - static double softoken3_version = -1; - static double nss3_version = -1; - static Provider pkcs11 = newPKCS11Provider(); + private boolean enableSM = false; public static Provider newPKCS11Provider() { - ServiceLoader sl = ServiceLoader.load(java.security.Provider.class); + ServiceLoader sl = ServiceLoader.load(java.security.Provider.class); Iterator iter = sl.iterator(); Provider p = null; boolean found = false; @@ -132,8 +137,8 @@ // Nothing found through ServiceLoader; fall back to reflection if (!found) { try { - Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11"); - p = (Provider) clazz.newInstance(); + Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11"); + p = (Provider) clazz.getDeclaredConstructor().newInstance(); } catch (Exception ex) { ex.printStackTrace(); } @@ -154,38 +159,6 @@ return p.configure(config); } - public abstract void main(Provider p) throws Exception; - - protected boolean skipTest(Provider p) { - return false; - } - - private void premain(Provider p) throws Exception { - if (skipTest(p)) { - return; - } - - // set a security manager and policy before a test case runs, - // and disable them after the test case finished - try { - if (enableSM) { - System.setSecurityManager(new SecurityManager()); - } - long start = System.currentTimeMillis(); - System.out.printf( - "Running test with provider %s (security manager %s) ...%n", - p.getName(), enableSM ? "enabled" : "disabled"); - main(p); - long stop = System.currentTimeMillis(); - System.out.println("Completed test with provider " + p.getName() + - " (" + (stop - start) + " ms)."); - } finally { - if (enableSM) { - System.setSecurityManager(null); - } - } - } - public static void main(PKCS11Test test) throws Exception { main(test, null); } @@ -210,19 +183,18 @@ Provider[] oldProviders = Security.getProviders(); try { System.out.println("Beginning test run " + test.getClass().getName() + "..."); - testDefault(test); testNSS(test); - testDeimos(test); + } finally { // NOTE: Do not place a 'return' in any finally block // as it will suppress exceptions and hide test failures. Provider[] newProviders = Security.getProviders(); boolean found = true; - // Do not restore providers if nothing changed. This is especailly + // Do not restore providers if nothing changed. This is especially // useful for ./Provider/Login.sh, where a SecurityManager exists. if (oldProviders.length == newProviders.length) { found = false; - for (int i = 0; i= '0' && c <= '9'); - c = s.charAt(++afterheader)) { - version += c; + c == '.' || (c >= '0' && c <= '9'); + c = s.charAt(++afterheader)) { + version.append(c); } // If a "dot dot" release, strip the extra dots for double parsing - String[] dot = version.split("\\."); + String[] dot = version.toString().split("\\."); if (dot.length > 2) { - version = dot[0]+"."+dot[1]; + version = new StringBuilder(dot[0] + "." + dot[1]); for (int j = 2; dot.length > j; j++) { - version += dot[j]; + version.append(dot[j]); } } // Convert to double for easier version value checking try { - nss_version = Double.parseDouble(version); + nss_version = Double.parseDouble(version.toString()); } catch (NumberFormatException e) { System.out.println("===== Content start ====="); System.out.println(s); @@ -516,7 +447,7 @@ e.printStackTrace(); } - System.out.print("lib" + library + " version = "+version+". "); + System.out.print("library: " + library + ", version: " + version + ". "); // Check for ECC if (s.indexOf("Basic") > 0) { @@ -545,13 +476,15 @@ // Run NSS testing on a Provider p configured with test nss config public static void testNSS(PKCS11Test test) throws Exception { + System.out.println("===> testNSS: Starting test run"); String nssConfig = getNssConfig(); if (nssConfig == null) { - // issue loading libraries - return; + throw new SkippedException("testNSS: Problem loading NSS libraries"); } + Provider p = getSunPKCS11(nssConfig); test.premain(p); + System.out.println("testNSS: Completed"); } public static String getNssConfig() throws Exception { @@ -560,7 +493,7 @@ return null; } - if (loadNSPR(libdir) == false) { + if (!loadNSPR(libdir)) { return null; } @@ -598,12 +531,12 @@ if (kcProp == null) { throw new RuntimeException( - "\"AlgorithmParameters.EC SupportedCurves property\" not found"); + "\"AlgorithmParameters.EC SupportedCurves property\" not found"); } System.out.println("Finding supported curves using list from SunEC\n"); index = 0; - for (;;) { + for (; ; ) { // Each set of curve names is enclosed with brackets. begin = kcProp.indexOf('[', index); end = kcProp.indexOf(']', index); @@ -620,12 +553,12 @@ end = kcProp.indexOf(',', begin); if (end == -1) { // Only one name in the set. - end = index -1; + end = index - 1; } curve = kcProp.substring(begin, end); getSupportedECParameterSpec(curve, p) - .ifPresent(spec -> results.add(spec)); + .ifPresent(spec -> results.add(spec)); } if (results.size() == 0) { @@ -636,9 +569,9 @@ } static Optional getSupportedECParameterSpec(String curve, - Provider p) throws Exception { + Provider p) throws Exception { ECParameterSpec e = getECParameterSpec(p, curve); - System.out.print("\t "+ curve + ": "); + System.out.print("\t " + curve + ": "); try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p); kpg.initialize(e); @@ -660,26 +593,13 @@ throws Exception { AlgorithmParameters parameters = - AlgorithmParameters.getInstance("EC", p); + AlgorithmParameters.getInstance("EC", p); parameters.init(new ECGenParameterSpec(name)); return parameters.getParameterSpec(ECParameterSpec.class); } - // Check support for a curve with a provided Vector of EC support - boolean checkSupport(List supportedEC, - ECParameterSpec curve) { - for (ECParameterSpec ec: supportedEC) { - if (ec.equals(curve)) { - return true; - } - } - return false; - } - - private static Map osMap; - // Location of the NSS libraries on each supported platform private static Map getOsMap() { if (osMap != null) { @@ -687,23 +607,26 @@ } osMap = new HashMap<>(); - osMap.put("Linux-i386-32", new String[] { + osMap.put("Linux-i386-32", new String[]{ "/usr/lib/i386-linux-gnu/", "/usr/lib32/", - "/usr/lib/" }); - osMap.put("Linux-amd64-64", new String[] { + "/usr/lib/"}); + osMap.put("Linux-amd64-64", new String[]{ "/usr/lib/x86_64-linux-gnu/", "/usr/lib/x86_64-linux-gnu/nss/", - "/usr/lib64/" }); - osMap.put("Linux-ppc64-64", new String[] { "/usr/lib64/" }); - osMap.put("Linux-ppc64le-64", new String[] { "/usr/lib64/" }); - osMap.put("Linux-s390x-64", new String[] { "/usr/lib64/" }); - osMap.put("Windows-x86-32", new String[] {}); - osMap.put("Windows-amd64-64", new String[] {}); - osMap.put("MacOSX-x86_64-64", new String[] {}); - osMap.put("Linux-arm-32", new String[] { + "/usr/lib64/"}); + osMap.put("Linux-ppc64-64", new String[]{"/usr/lib64/"}); + osMap.put("Linux-ppc64le-64", new String[]{ + "/usr/lib/powerpc64le-linux-gnu/", + "/usr/lib/powerpc64le-linux-gnu/nss/", + "/usr/lib64/"}); + osMap.put("Linux-s390x-64", new String[]{"/usr/lib64/"}); + osMap.put("Windows-x86-32", new String[]{}); + osMap.put("Windows-amd64-64", new String[]{}); + osMap.put("MacOSX-x86_64-64", new String[]{}); + osMap.put("Linux-arm-32", new String[]{ "/usr/lib/arm-linux-gnueabi/nss/", - "/usr/lib/arm-linux-gnueabihf/nss/" }); + "/usr/lib/arm-linux-gnueabihf/nss/"}); // Exclude linux-aarch64 at the moment until the following bug is fixed: // 8296631: NSS tests failing on OL9 linux-aarch64 hosts // osMap.put("Linux-aarch64-64", new String[] { @@ -744,11 +667,9 @@ } } - return nssLibPaths.toArray(new String[nssLibPaths.size()]); + return nssLibPaths.toArray(new String[0]); } - private final static char[] hexDigits = "0123456789abcdef".toCharArray(); - public static String toString(byte[] b) { if (b == null) { return "(null)"; @@ -759,8 +680,8 @@ if (i != 0) { sb.append(':'); } - sb.append(hexDigits[k >>> 4]); - sb.append(hexDigits[k & 0xf]); + sb.append(HEX_DIGITS[k >>> 4]); + sb.append(HEX_DIGITS[k & 0xf]); } return sb.toString(); } @@ -806,20 +727,11 @@ } } - T[] concat(T[] a, T[] b) { - if ((b == null) || (b.length == 0)) { - return a; - } - T[] r = Arrays.copyOf(a, a.length + b.length); - System.arraycopy(b, 0, r, a.length, b.length); - return r; - } - /** * Returns supported algorithms of specified type. */ static List getSupportedAlgorithms(String type, String alg, - Provider p) { + Provider p) { // prepare a list of supported algorithms List algorithms = new ArrayList<>(); Set services = p.getServices(); @@ -832,8 +744,6 @@ return algorithms; } - private static final SecureRandom srdm = new SecureRandom(); - static SecretKey generateKey(String alg, int keySize) { if (alg.contains("PBE")) { return generateKeyPBE(alg, keySize); @@ -861,22 +771,27 @@ public String getAlgorithm() { return "PBE"; } + @Override public String getFormat() { return null; } + @Override public byte[] getEncoded() { throw new RuntimeException("Should not be called"); } + @Override public char[] getPassword() { return pass; } + @Override public byte[] getSalt() { return salt; } + @Override public int getIterationCount() { return iterations; @@ -886,7 +801,7 @@ static byte[] generateData(int length) { byte data[] = new byte[length]; - for (int i=0; i supportedEC, + ECParameterSpec curve) { + for (ECParameterSpec ec : supportedEC) { + if (ec.equals(curve)) { + return true; + } + } + return false; + } + + T[] concat(T[] a, T[] b) { + if ((b == null) || (b.length == 0)) { + return a; + } + T[] r = Arrays.copyOf(a, a.length + b.length); + System.arraycopy(b, 0, r, a.length, b.length); + return r; + } + protected void setCommonSystemProps() { System.setProperty("java.security.debug", "true"); - System.setProperty("NO_DEIMOS", "true"); - System.setProperty("NO_DEFAULT", "true"); System.setProperty("CUSTOM_DB_DIR", TEST_CLASSES); } @@ -956,31 +921,38 @@ StandardCopyOption.REPLACE_EXISTING); } + // NSS version info + public static enum ECCState {None, Basic, Extended} + @Artifact( organization = "jpg.tests.jdk.nsslib", name = "nsslib-windows_x64", revision = "3.46-VS2017", extension = "zip") - private static class WINDOWS_X64 { } + private static class WINDOWS_X64 { + } @Artifact( organization = "jpg.tests.jdk.nsslib", name = "nsslib-windows_x86", revision = "3.46-VS2017", extension = "zip") - private static class WINDOWS_X86 { } + private static class WINDOWS_X86 { + } @Artifact( organization = "jpg.tests.jdk.nsslib", name = "nsslib-macosx_x64", revision = "3.46", extension = "zip") - private static class MACOSX_X64 { } + private static class MACOSX_X64 { + } @Artifact( organization = "jpg.tests.jdk.nsslib", name = "nsslib-linux_x64", revision = "3.46", extension = "zip") - private static class LINUX_X64 { } + private static class LINUX_X64 { + } } diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -28,6 +28,8 @@ * @run testng/othervm ConfigQuotedString */ +import jtreg.SkippedException; +import org.testng.SkipException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -44,7 +46,11 @@ @Test public void testQuotedString() throws Exception { - main(new ConfigQuotedString()); + try { + main(new ConfigQuotedString()); + } catch (SkippedException se) { + throw new SkipException("One or more tests are skipped"); + } } public void main(Provider p) throws Exception { diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/Provider/Login.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/Provider/Login.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/Provider/Login.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/Provider/Login.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -28,6 +28,8 @@ * @run testng/othervm -Djava.security.manager=allow Login */ +import jtreg.SkippedException; +import org.testng.SkipException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -55,7 +57,11 @@ @Test public void testLogin() throws Exception { String[] args = new String[]{ "sm", "Login.policy"}; - main(new Login(), args); + try { + main(new Login(), args); + } catch (SkippedException se) { + throw new SkipException("One or more tests are skipped"); + } } public void main(Provider p) throws Exception { diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2021, 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 @@ -111,6 +111,7 @@ --add-modules jdk.crypto.cryptoki \ --add-exports jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED \ ${TESTSRC}${FS}..${FS}..${FS}..${FS}..${FS}..${FS}lib${FS}jdk${FS}test${FS}lib${FS}artifacts${FS}*.java \ + ${TESTSRC}${FS}..${FS}..${FS}..${FS}..${FS}..${FS}lib${FS}jtreg${FS}*.java \ ${TESTSRC}${FS}MultipleLogins.java \ ${TESTSRC}${FS}..${FS}PKCS11Test.java @@ -119,8 +120,6 @@ --add-exports jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED \ -DCUSTOM_DB_DIR=${TESTCLASSES} \ -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}MultipleLogins-nss.txt \ - -DNO_DEFAULT=true \ - -DNO_DEIMOS=true \ -Dtest.src=${TESTSRC} \ -Dtest.classes=${TESTCLASSES} \ -Djava.security.debug=${DEBUG}" diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/SecmodTest.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/SecmodTest.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/SecmodTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/SecmodTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, 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 @@ -24,6 +24,8 @@ // common infrastructure for Secmod tests +import jtreg.SkippedException; + import java.io.*; import java.security.Provider; @@ -43,13 +45,11 @@ static boolean initSecmod() throws Exception { useNSS(); LIBPATH = getNSSLibDir(); - if (LIBPATH == null) { - return false; - } // load all the libraries except libnss3 into memory - if (loadNSPR(LIBPATH) == false) { - return false; + if ((LIBPATH == null) || (!loadNSPR(LIBPATH))) { + throw new SkippedException("Failed to load NSS libraries"); } + safeReload(LIBPATH + System.mapLibraryName("softokn3")); safeReload(LIBPATH + System.mapLibraryName("nssckbi")); diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, 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 diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/nss/p11-deimos.txt openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/nss/p11-deimos.txt --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/nss/p11-deimos.txt 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/nss/p11-deimos.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -# -# -# -# Configuration to run unit tests with the Deimos (SCA1000) software -# - -name = Deimos - -#showInfo = true - -library = /opt/SUNWconn/lib/libpkcs11.so - -attributes = compatibility - diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/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. * @@ -39,7 +39,7 @@ * @library /test/lib .. * @run main/othervm TestP11KeyFactoryGetRSAKeySpec * @run main/othervm -Djava.security.manager=allow TestP11KeyFactoryGetRSAKeySpec sm rsakeys.ks.policy - * @run main/othervm -DCUSTOM_P11_CONFIG_NAME=p11-nss-sensitive.txt -DNO_DEIMOS=true -DNO_DEFAULT=true TestP11KeyFactoryGetRSAKeySpec + * @run main/othervm -DCUSTOM_P11_CONFIG_NAME=p11-nss-sensitive.txt TestP11KeyFactoryGetRSAKeySpec * @modules jdk.crypto.cryptoki */ diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, 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 @@ -37,7 +37,7 @@ * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" * ClientJSSEServerJSSE * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" - * ClientJSSEServerJSSE sm policy + * -Djava.security.manager=allow ClientJSSEServerJSSE sm policy */ import java.security.Provider; diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/rsa/SignedObjectChain.java openjdk-21-21.0.2+13/test/jdk/sun/security/rsa/SignedObjectChain.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/rsa/SignedObjectChain.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/rsa/SignedObjectChain.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, 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 @@ -21,6 +21,8 @@ * questions. */ +import java.util.Arrays; + /* * @test * @bug 8050374 8146293 @@ -31,7 +33,6 @@ * @summary Verify a chain of signed objects */ public class SignedObjectChain { - private static class Test extends Chain.Test { public Test(Chain.SigAlg sigAlg) { @@ -52,10 +53,9 @@ }; public static void main(String argv[]) { - boolean resutl = java.util.Arrays.stream(tests).allMatch( - (test) -> Chain.runTest(test)); + boolean result = Arrays.stream(tests).parallel().allMatch(Chain::runTest); - if(resutl) { + if (result) { System.out.println("All tests passed"); } else { throw new RuntimeException("Some tests failed"); diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/rsa/WithoutNULL.java openjdk-21-21.0.2+13/test/jdk/sun/security/rsa/WithoutNULL.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/rsa/WithoutNULL.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/rsa/WithoutNULL.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * 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 8320597 + * @summary Verify RSA signature with omitted digest params (should be encoded as NULL) + * for backward compatibility + */ +import java.security.KeyFactory; +import java.security.Signature; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class WithoutNULL { + public static void main(String[] args) throws Exception { + + // A 1024-bit RSA public key + byte[] key = Base64.getMimeDecoder().decode(""" + MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrfTrEm4KvdFSpGAM7InrFEzALTKdphT9fK6Gu + eVjHtKsuCSEaULCdjhJvPpFK40ONr1JEC1Ywp1UYrfBBdKunnbDZqNZL1cFv+IzF4Yj6JO6pOeHi + 1Zpur1GaQRRlYTvzmyWY/AATQDh8JfKObNnDVwXeezFODUG8h5+XL1ZXZQIDAQAB"""); + + // A SHA1withRSA signature on an empty input where the digestAlgorithm + // inside DigestInfo does not have a parameters field. + byte[] sig = Base64.getMimeDecoder().decode(""" + D1FpiT44WEXlDfYK880bdorLO+e9qJVXZWiBgqs9dfK7lYQwyEt9dL23mbUAKm5TVEj2ZxtHkEvk + b8oaWkxk069jDTM1RhllPJZkAjeQRbw4gkg4N6wKZz9B/jdSRMNJg/b9QdRYZOHOBxsEHMbUREPV + DoCOLaxB8eIXX0EWkiE="""); + + Signature s = Signature.getInstance("SHA1withRSA", "SunRsaSign"); + s.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(key))); + if (!s.verify(sig)) { + throw new RuntimeException("Does not verify"); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java openjdk-21-21.0.2+13/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 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 @@ -29,7 +29,8 @@ /* * @test * @bug 8224829 - * @summary AsyncSSLSocketClose.java has timing issue + * @summary AsyncSSLSocketClose.java has timing issue. + * @library /javax/net/ssl/templates * @run main/othervm BlockedAsyncClose */ @@ -38,52 +39,41 @@ import java.net.SocketException; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; -public class BlockedAsyncClose implements Runnable { +/* + * To manually verify that the write thread was blocked when socket.close() is called, + * run the test with -Djavax.net.debug=ssl. You should see the message + * "SSLSocket output duplex close failed: SO_LINGER timeout, close_notify message cannot be sent." + */ +public class BlockedAsyncClose extends SSLContextTemplate implements Runnable { SSLSocket socket; SSLServerSocket ss; // Is the socket ready to close? private final CountDownLatch closeCondition = new CountDownLatch(1); - - // Where do we find the keystores? - static String pathToStores = "../../../../javax/net/ssl/etc"; - static String keyStoreFile = "keystore"; - static String trustStoreFile = "truststore"; - static String passwd = "passphrase"; + private final Lock writeLock = new ReentrantLock(); public static void main(String[] args) throws Exception { - String keyFilename = - System.getProperty("test.src", "./") + "/" + pathToStores + - "/" + keyStoreFile; - String trustFilename = - System.getProperty("test.src", "./") + "/" + pathToStores + - "/" + trustStoreFile; - - System.setProperty("javax.net.ssl.keyStore", keyFilename); - System.setProperty("javax.net.ssl.keyStorePassword", passwd); - System.setProperty("javax.net.ssl.trustStore", trustFilename); - System.setProperty("javax.net.ssl.trustStorePassword", passwd); - - new BlockedAsyncClose(); + new BlockedAsyncClose().runTest(); } - public BlockedAsyncClose() throws Exception { - SSLServerSocketFactory sslssf = - (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); + public void runTest() throws Exception { + SSLServerSocketFactory sslssf = createServerSSLContext().getServerSocketFactory(); InetAddress loopback = InetAddress.getLoopbackAddress(); ss = (SSLServerSocket)sslssf.createServerSocket(); ss.bind(new InetSocketAddress(loopback, 0)); - SSLSocketFactory sslsf = - (SSLSocketFactory)SSLSocketFactory.getDefault(); + SSLSocketFactory sslsf = createClientSSLContext().getSocketFactory(); socket = (SSLSocket)sslsf.createSocket(loopback, ss.getLocalPort()); SSLSocket serverSoc = (SSLSocket)ss.accept(); ss.close(); - (new Thread(this)).start(); + new Thread(this).start(); serverSoc.startHandshake(); boolean closeIsReady = closeCondition.await(90L, TimeUnit.SECONDS); @@ -94,23 +84,22 @@ } socket.setSoLinger(true, 10); - System.out.println("Calling Socket.close"); - // Sleep for a while so that the write thread blocks by hitting the - // output stream buffer limit. - Thread.sleep(1000); + // if the writeLock is not released by the other thread within 10 + // seconds it is probably blocked, and we can try to close the socket + while (writeLock.tryLock(10, TimeUnit.SECONDS)) { + writeLock.unlock(); + } + System.out.println("Calling socket.close()"); socket.close(); - System.out.println("ssl socket get closed"); System.out.flush(); } // block in write public void run() { byte[] ba = new byte[1024]; - for (int i = 0; i < ba.length; i++) { - ba[i] = 0x7A; - } + Arrays.fill(ba, (byte) 0x7A); try { OutputStream os = socket.getOutputStream(); @@ -128,8 +117,16 @@ // write more while (true) { count += ba.length; + System.out.println(count + " bytes to be written"); + + writeLock.lock(); os.write(ba); + // This isn't in a try/finally. If an exception is thrown + // and the lock is released, the main thread will + // loop until the test times out. So don't release it. + writeLock.unlock(); + System.out.println(count + " bytes written"); } } catch (SocketException se) { @@ -144,4 +141,3 @@ } } } - diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java openjdk-21-21.0.2+13/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java 2024-01-16 16:19:00.000000000 +0000 @@ -137,7 +137,8 @@ System.out.println("server ready"); Socket baseSocket = new Socket("localhost", serverPort); - baseSocket.setSoTimeout(1000); + float timeoutFactor = Float.parseFloat(System.getProperty("test.timeout.factor", "1.0")); + baseSocket.setSoTimeout((int)(1000 * timeoutFactor)); SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault(); diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/tools/jarsigner/Warning.java openjdk-21-21.0.2+13/test/jdk/sun/security/tools/jarsigner/Warning.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/tools/jarsigner/Warning.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/tools/jarsigner/Warning.java 2024-01-16 16:19:00.000000000 +0000 @@ -36,7 +36,7 @@ * @summary warnings, errors and -strict * @library /lib/testlibrary /test/lib * @build jdk.test.lib.util.JarUtils - * @run main Warning + * @run main/othervm/timeout=400 Warning */ public class Warning { diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/security/util/math/TestIntegerModuloP.java openjdk-21-21.0.2+13/test/jdk/sun/security/util/math/TestIntegerModuloP.java --- openjdk-21-21.0.1+12/test/jdk/sun/security/util/math/TestIntegerModuloP.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/security/util/math/TestIntegerModuloP.java 2024-01-16 16:19:00.000000000 +0000 @@ -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,21 +22,81 @@ */ /* - * @test + * @test id=IntegerPolynomial25519 * @bug 8181594 8208648 * @summary Test proper operation of integer field arithmetic * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomial25519 32 0 + */ + + /* + * @test id=IntegerPolynomial448 + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomial448 56 1 + */ + + /* + * @test id=IntegerPolynomial1305 + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomial1305 16 2 + */ + + /* + * @test id=IntegerPolynomialP256 + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomialP256 32 5 + */ + + /* + * @test id=IntegerPolynomialP384 + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomialP384 48 6 + */ + + /* + * @test id=IntegerPolynomialP521 + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomialP521 66 7 + */ + + /* + * @test id=P256OrderField + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.P256OrderField 32 8 + */ + + /* + * @test id=P384OrderField + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.P384OrderField 48 9 + */ + + /* + * @test id=P521OrderField + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.P521OrderField 66 10 + */ + + /* + * @test id=Curve25519OrderField + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.Curve25519OrderField 32 11 + */ + + /* + * @test id=Curve448OrderField + * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly + * @build BigIntegerModuloP * @run main TestIntegerModuloP sun.security.util.math.intpoly.Curve448OrderField 56 12 */ diff -Nru openjdk-21-21.0.1+12/test/jdk/sun/tools/jstatd/JstatdTest.java openjdk-21-21.0.2+13/test/jdk/sun/tools/jstatd/JstatdTest.java --- openjdk-21-21.0.1+12/test/jdk/sun/tools/jstatd/JstatdTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/sun/tools/jstatd/JstatdTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -65,6 +65,8 @@ private static final int JSTAT_GCUTIL_INTERVAL_MS = 250; private static final String JPS_OUTPUT_REGEX = "^\\d+\\s*.*"; + private static final int MAX_JSTATD_TRIES = 10; + private boolean useDefaultPort = true; private boolean useDefaultRmiPort = true; private String port; @@ -282,7 +284,7 @@ private ProcessThread tryToSetupJstatdProcess() throws Throwable { portInUse = false; ProcessThread jstatdThread = new ProcessThread("Jstatd-Thread", - JstatdTest::isJstadReady, getJstatdCmd()); + JstatdTest::isJstatdReady, getJstatdCmd()); try { jstatdThread.start(); // Make sure jstatd is up and running @@ -302,8 +304,8 @@ return jstatdThread; } - private static boolean isJstadReady(String line) { - if (line.contains("Port already in use")) { + private static boolean isJstatdReady(String line) { + if (line.contains("Port already in use") || line.contains("Could not bind")) { portInUse = true; return true; } @@ -322,8 +324,9 @@ } ProcessThread jstatdThread = null; + int tries = 0; try { - while (jstatdThread == null) { + while (jstatdThread == null && ++tries <= MAX_JSTATD_TRIES) { if (!useDefaultPort) { port = String.valueOf(Utils.getFreePort()); } @@ -339,10 +342,11 @@ continue; } } - jstatdThread = tryToSetupJstatdProcess(); } - + if (jstatdThread == null) { + throw new RuntimeException("Cannot start jstatd."); + } runToolsAndVerify(); } finally { cleanUpThread(jstatdThread); diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.compiler.CompilerUtils; +import tests.JImageGenerator; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/* + * @test + * @summary Make sure that modules can be linked using jlink + * and deduplication works correctly when creating sub methods + * @bug 8311591 + * @library /test/lib + * ../lib + * @modules java.base/jdk.internal.jimage + * jdk.jdeps/com.sun.tools.classfile + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.plugin + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* JLinkDedupTestBatchSizeOne jdk.test.lib.compiler.CompilerUtils + * @run main/othervm -Xmx1g -Xlog:init=debug -XX:+UnlockDiagnosticVMOptions -XX:+BytecodeVerificationLocal JLinkDedupTestBatchSizeOne + */ +public class JLinkDedupTestBatchSizeOne { + + private static final String JAVA_HOME = System.getProperty("java.home"); + private static final String TEST_SRC = System.getProperty("test.src"); + + private static final Path SRC_DIR = Paths.get(TEST_SRC, "dedup", "src"); + private static final Path MODS_DIR = Paths.get("mods"); + + private static final String MODULE_PATH = + Paths.get(JAVA_HOME, "jmods").toString() + + File.pathSeparator + MODS_DIR.toString(); + + // the names of the modules in this test + private static String[] modules = new String[]{"m1", "m2", "m3", "m4"}; + + private static boolean hasJmods() { + if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) { + System.err.println("Test skipped. No jmods directory"); + return false; + } + return true; + } + + public static void compileAll() throws Throwable { + if (!hasJmods()) return; + + for (String mn : modules) { + Path msrc = SRC_DIR.resolve(mn); + CompilerUtils.compile(msrc, MODS_DIR, + "--module-source-path", SRC_DIR.toString()); + } + } + + public static void main(String[] args) throws Throwable { + compileAll(); + Path image = Paths.get("bug8311591"); + + JImageGenerator.getJLinkTask() + .modulePath(MODULE_PATH) + .output(image.resolve("out-jlink-dedup")) + .addMods("m1") + .addMods("m2") + .addMods("m3") + .addMods("m4") + .option("--system-modules=batch-size=1") + .call() + .assertSuccess(); + + Path binDir = image.resolve("out-jlink-dedup").resolve("bin").toAbsolutePath(); + Path bin = binDir.resolve("java"); + + ProcessBuilder processBuilder = new ProcessBuilder(bin.toString(), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+BytecodeVerificationLocal", + "-m", "m4/p4.Main"); + processBuilder.inheritIO(); + processBuilder.directory(binDir.toFile()); + Process process = processBuilder.start(); + int exitCode = process.waitFor(); + if (exitCode != 0) + throw new AssertionError("JLinkDedupTest100Modules failed to launch"); + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m1/module-info.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m1/module-info.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m1/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m1/module-info.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * 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 p1.AInterface; +import p3.ServiceInterface; + +module m1 { + exports p1 to m4; + + opens p1 to m4; + + requires transitive java.desktop; + requires m3; + + provides ServiceInterface with AInterface; +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m1/p1/AInterface.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m1/p1/AInterface.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m1/p1/AInterface.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m1/p1/AInterface.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * 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 p1; +import p3.ServiceInterface; + +public class AInterface implements ServiceInterface { + + public String getString() { + return "A1_A2"; + } + + public String getServiceName() { + return "AService"; + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m2/module-info.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m2/module-info.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m2/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m2/module-info.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * 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 p2.BInterface; +import p3.ServiceInterface; + +module m2 { + exports p2 to m3,m4; + + opens p2 to m4; + + requires transitive java.desktop; + requires m3; + + provides ServiceInterface with BInterface; +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m2/p2/BInterface.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m2/p2/BInterface.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m2/p2/BInterface.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m2/p2/BInterface.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * 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 p2; +import p3.ServiceInterface; +public class BInterface implements ServiceInterface { + + public String getString() { + return "B1_B2"; + } + + public String getServiceName() { + return "BService"; + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m3/module-info.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m3/module-info.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m3/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m3/module-info.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * 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. + */ + +module m3 { + exports p3; +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m3/p3/ServiceInterface.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m3/p3/ServiceInterface.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m3/p3/ServiceInterface.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m3/p3/ServiceInterface.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * 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 p3; +public interface ServiceInterface { + + String getString(); + + String getServiceName(); +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m4/module-info.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m4/module-info.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m4/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m4/module-info.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * 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 p3.ServiceInterface; + +module m4 { + requires m3; + requires transitive java.desktop; + uses ServiceInterface; +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m4/p4/Main.java openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m4/p4/Main.java --- openjdk-21-21.0.1+12/test/jdk/tools/jlink/dedup/src/m4/p4/Main.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jlink/dedup/src/m4/p4/Main.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * 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 p4; + +import p3.ServiceInterface; + +import java.lang.module.ModuleFinder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.ServiceLoader; + +public class Main { + + public static void main(String[] args) throws Exception { + List services = getServices(); + for (var service : services) { + System.out.println("Service name " + service.getServiceName()); + System.out.println("Service string " + service.getString()); + } + var moduleClass = Class.forName("jdk.internal.module.SystemModules$all"); + long subMethodCount = Arrays.stream(moduleClass.getDeclaredMethods()) + .filter(method -> method.getName().startsWith("sub")) + .count(); + + // one subX method per each module is generated as the image is linked with + // --system-modules=batchSize=1 + var moduleCount = (long) ModuleFinder.ofSystem().findAll().size(); + if (subMethodCount != moduleCount) { + throw new AssertionError("Difference in generated sub module methods count! Expected: " + + moduleCount + " but was " + subMethodCount); + } + } + + private static List getServices() { + List services = new ArrayList<>(); + ServiceLoader.load(ServiceInterface.class).forEach(services::add); + return services; + } +} diff -Nru openjdk-21-21.0.1+12/test/jdk/tools/jpackage/windows/Win8301247Test.java openjdk-21-21.0.2+13/test/jdk/tools/jpackage/windows/Win8301247Test.java --- openjdk-21-21.0.1+12/test/jdk/tools/jpackage/windows/Win8301247Test.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/jdk/tools/jpackage/windows/Win8301247Test.java 2024-01-16 16:19:00.000000000 +0000 @@ -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.io.IOException; +import java.time.Duration; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Executor; +import jdk.jpackage.test.HelloApp; +import jdk.jpackage.test.TKit; + +/** + * Test that terminating of the parent app launcher process automatically + * terminates child app launcher process. + */ + +/* + * @test + * @summary Test case for JDK-8301247 + * @library ../helpers + * @build jdk.jpackage.test.* + * @build Win8301247Test + * @requires (os.family == "windows") + * @modules jdk.jpackage/jdk.jpackage.internal + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=Win8301247Test + */ +public class Win8301247Test { + + @Test + public void test() throws IOException, InterruptedException { + JPackageCommand cmd = JPackageCommand.helloAppImage(); + + // Launch the app in a way it doesn't exit to let us trap app laucnher + // processes in the process list + cmd.addArguments("--java-options", "-Djpackage.test.noexit=true"); + cmd.executeAndAssertImageCreated(); + + if (!cmd.canRunLauncher("Not running the test")) { + return; + } + + try ( // Launch the app in a separate thread + ExecutorService exec = Executors.newSingleThreadExecutor()) { + exec.execute(() -> { + HelloApp.executeLauncher(cmd); + }); + + // Wait a bit to let the app start + Thread.sleep(Duration.ofSeconds(10)); + + // Get PID of the main app launcher process + final long pid = findMainAppLauncherPID(cmd, 2).get(); + + // Kill the main app launcher process + Executor.of("taskkill", "/F", "/PID", Long.toString(pid)). + dumpOutput(true).execute(); + + // Wait a bit and check if child app launcher process is still running (it must NOT) + Thread.sleep(Duration.ofSeconds(5)); + + findMainAppLauncherPID(cmd, 0); + } + } + + private static Optional findMainAppLauncherPID(JPackageCommand cmd, + int expectedCount) { + // Get the list of PIDs and PPIDs of app launcher processes. + // wmic process where (name = "foo.exe") get ProcessID,ParentProcessID + List output = Executor.of("wmic", "process", "where", "(name", + "=", + "\"" + cmd.appLauncherPath().getFileName().toString() + "\"", + ")", "get", "ProcessID,ParentProcessID").dumpOutput(true). + saveOutput().executeAndGetOutput(); + + if (expectedCount == 0) { + TKit.assertEquals("No Instance(s) Available.", output.getFirst(). + trim(), "Check no app launcher processes found running"); + return Optional.empty(); + } + + String[] headers = Stream.of(output.getFirst().split("\\s+", 2)).map( + String::trim).map(String::toLowerCase).toArray(String[]::new); + Pattern pattern; + if (headers[0].equals("parentprocessid") && headers[1].equals( + "processid")) { + pattern = Pattern.compile("^(?\\d+)\\s+(?\\d+)\\s+$"); + } else if (headers[1].equals("parentprocessid") && headers[0].equals( + "processid")) { + pattern = Pattern.compile("^(?\\d+)\\s+(?\\d+)\\s+$"); + } else { + throw new RuntimeException( + "Unrecognizable output of \'wmic process\' command"); + } + + List processes = output.stream().skip(1).map(line -> { + Matcher m = pattern.matcher(line); + long[] pids = null; + if (m.matches()) { + pids = new long[]{Long.parseLong(m.group("pid")), Long. + parseLong(m.group("ppid"))}; + } + return pids; + }).filter(Objects::nonNull).toList(); + + TKit.assertEquals(expectedCount, processes.size(), String.format( + "Check [%d] app launcher processes found running", expectedCount)); + + switch (expectedCount) { + case 2 -> { + if (processes.get(0)[0] == processes.get(1)[1]) { + return Optional.of(processes.get(0)[0]); + } else if (processes.get(1)[0] == processes.get(0)[1]) { + return Optional.of(processes.get(1)[0]); + } else { + throw new RuntimeException( + "App launcher processes unrelated"); + } + } + default -> + throw new IllegalArgumentException(); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/langtools/TEST.ROOT openjdk-21-21.0.2+13/test/langtools/TEST.ROOT --- openjdk-21-21.0.1+12/test/langtools/TEST.ROOT 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/TEST.ROOT 2024-01-16 16:19:00.000000000 +0000 @@ -15,7 +15,7 @@ groups=TEST.groups # Minimum jtreg version -requiredVersion=7.2+1 +requiredVersion=7.3.1+1 # Use new module options useNewOptions=true diff -Nru openjdk-21-21.0.1+12/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java openjdk-21-21.0.2+13/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java --- openjdk-21-21.0.1+12/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8266666 8281969 + * @bug 8266666 8281969 8319339 * @summary Implementation for snippets * @library /tools/lib ../../lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -259,8 +259,12 @@ Path srcDir = base.resolve("src"); Path outDir = base.resolve("out"); var goodFile = "good.txt"; + // use two files that differ in name but not content, to work around + // error deduplication, whereby an error related to coordinates + // (file, pos) reported before is suppressed; see: + // com.sun.tools.javac.util.Log.shouldReport(JavaFileObject, int) var badFile = "bad.txt"; - var badFile2 = "bad2.txt"; // to workaround error deduplication + var badFile2 = "bad2.txt"; new ClassBuilder(tb, "pkg.A") .setModifiers("public", "class") .addMembers( @@ -625,7 +629,7 @@ } @Test - public void testPositiveInlineTagMarkup_FalseMarkup(Path base) throws Exception { + public void testPositiveInlineTagMarkup_SpuriousMarkup(Path base) throws Exception { var testCases = List.of( new TestCase( """ @@ -661,6 +665,134 @@ """) ); testPositive(base, testCases); + checkOutput(Output.OUT, true, """ + A.java:6: warning: spurious markup + // @formatter:off + ^""",""" + A.java:9: warning: spurious markup + // @formatter:on + ^""",""" + A.java:17: warning: spurious markup + // @formatter:off + ^""",""" + A.java:22: warning: spurious markup + // @formatter:on + ^"""); + } + + /* + * If spurious markup appears in an external snippet or either side of a + * hybrid snippet, then all of the below is true: + * + * - no error is raised + * - relevant warnings are emitted + * - spurious markup is output literally + */ + @Test + public void testPositiveExternalHybridTagMarkup_SpuriousMarkup(Path base) throws Exception { + Path srcDir = base.resolve("src"); + Path outDir = base.resolve("out"); + var plain = "plain.txt"; + var withRegion = "withRegion.txt"; + new ClassBuilder(tb, "pkg.A") + .setModifiers("public", "class") + .addMembers( + ClassBuilder.MethodBuilder + .parse("public void external() { }") + .setComments(""" + {@snippet file="%s"} + """.formatted(plain))) + .addMembers( + ClassBuilder.MethodBuilder + .parse("public void hybrid1() { }") + .setComments(""" + {@snippet file="%s": + First line + // @formatter:off + Second Line + Third line + // @formatter:on + Fourth line + } + """.formatted(plain))) + .addMembers( + ClassBuilder.MethodBuilder + .parse("public void hybrid2() { }") + .setComments(""" + {@snippet file="%s" region="showThis" : + Second Line + Third line + } + """.formatted(withRegion))) + .addMembers( + ClassBuilder.MethodBuilder + .parse("public void hybrid3() { }") + .setComments(""" + {@snippet file="%s" region="showThis" : + First line + // @formatter:off + Second Line // @start region=showThis + Third line + // @end + // @formatter:on + Fourth line + } + """.formatted(withRegion))) + .write(srcDir); + + addSnippetFile(srcDir, "pkg", plain, """ + First line + // @formatter:off + Second Line + Third line + // @formatter:on + Fourth line +"""); + addSnippetFile(srcDir, "pkg", withRegion, """ + First line + // @formatter:off + Second Line // @start region=showThis + Third line + // @end + // @formatter:on + Fourth line +"""); + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "pkg"); + checkExit(Exit.OK); + checkNoCrashes(); + checkOutput(Output.OUT, true, """ + %s:2: warning: spurious markup + // @formatter:off + ^""".formatted(plain), """ + %s:5: warning: spurious markup + // @formatter:on + ^""".formatted(plain), """ + A.java:11: warning: spurious markup + // @formatter:off + ^""", """ + A.java:14: warning: spurious markup + // @formatter:on + ^""", """ + %s:2: warning: spurious markup + // @formatter:off + ^""".formatted(plain), """ + %s:5: warning: spurious markup + // @formatter:on + ^""".formatted(plain), """ + %s:2: warning: spurious markup + // @formatter:off + ^""".formatted(withRegion), """ + %s:6: warning: spurious markup + // @formatter:on + ^""".formatted(withRegion), """ + A.java:31: warning: spurious markup + // @formatter:off + ^""", """ + A.java:35: warning: spurious markup + // @formatter:on + ^"""); } @Test diff -Nru openjdk-21-21.0.1+12/test/langtools/jdk/jshell/ClassesTest.java openjdk-21-21.0.2+13/test/langtools/jdk/jshell/ClassesTest.java --- openjdk-21-21.0.1+12/test/langtools/jdk/jshell/ClassesTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/jdk/jshell/ClassesTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8145239 8129559 8080354 8189248 8010319 8246353 8247456 8282160 8292755 + * @bug 8145239 8129559 8080354 8189248 8010319 8246353 8247456 8282160 8292755 8319532 * @summary Tests for EvaluationState.classes * @build KullaTesting TestingInputStream ExpectedDiagnostic * @run testng ClassesTest @@ -374,4 +374,11 @@ """); } + public void testNonSealed() { + assertAnalyze("non-sealed class C extends B {}int i;", + "non-sealed class C extends B {}", + "int i;", + true); + } + } diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/parser/JavacParserTest.java openjdk-21-21.0.2+13/test/langtools/tools/javac/parser/JavacParserTest.java --- openjdk-21-21.0.1+12/test/langtools/tools/javac/parser/JavacParserTest.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/parser/JavacParserTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -23,7 +23,8 @@ /* * @test - * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 8271928 8275097 8293897 8295401 8304671 8312093 + * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 8271928 8275097 8293897 8295401 8304671 8312093 8315452 + * @summary tests error and diagnostics positions * @author Jan Lahoda * @modules jdk.compiler/com.sun.tools.javac.api @@ -60,6 +61,8 @@ import com.sun.tools.javac.tree.JCTree; import java.io.IOException; import java.io.StringWriter; +import java.io.UncheckedIOException; +import java.io.Writer; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -70,6 +73,7 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.regex.Pattern; import javax.lang.model.element.Modifier; import javax.lang.model.type.TypeKind; @@ -88,7 +92,8 @@ import com.sun.source.util.TreePathScanner; import com.sun.tools.javac.api.JavacTaskPool; import com.sun.tools.javac.api.JavacTaskPool.Worker; -import java.util.Objects; +import com.sun.tools.javac.tree.JCTree.JCErroneous; +import com.sun.tools.javac.tree.Pretty; public class JavacParserTest extends TestCase { static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); @@ -2423,6 +2428,28 @@ }.scan(cut, null); } + @Test //JDK-8315452 + void testPartialTopLevelModifiers() throws IOException { + String code = """ + package test; + public + """; + DiagnosticCollector coll = + new DiagnosticCollector<>(); + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll, + List.of("--enable-preview", "--source", SOURCE_VERSION), + null, Arrays.asList(new MyFileObject(code))); + CompilationUnitTree cut = ct.parse().iterator().next(); + + String result = toStringWithErrors(cut).replaceAll("\\R", "\n"); + System.out.println("RESULT\n" + result); + assertEquals("incorrect AST", + result, + """ + package test; + (ERROR: public )"""); + } + void run(String[] args) throws Exception { int passed = 0, failed = 0; final Pattern p = (args != null && args.length > 0) @@ -2452,6 +2479,38 @@ passed + ", failed = " + failed + " ??????????"); } } + + private String toStringWithErrors(Tree tree) { + StringWriter s = new StringWriter(); + try { + new PrettyWithErrors(s, false).printExpr((JCTree) tree); + } catch (IOException e) { + // should never happen, because StringWriter is defined + // never to throw any IOExceptions + throw new AssertionError(e); + } + return s.toString(); + } + + private static final class PrettyWithErrors extends Pretty { + + public PrettyWithErrors(Writer out, boolean sourceOutput) { + super(out, sourceOutput); + } + + @Override + public void visitErroneous(JCErroneous tree) { + try { + print("(ERROR: "); + print(tree.errs); + print(")"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + } + } abstract class TestCase { diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/SwitchEnumConstants.java openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/SwitchEnumConstants.java --- openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/SwitchEnumConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/SwitchEnumConstants.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * 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 8318144 + * @summary Verify switches work in presence of enum constants that have bodies + * @compile SwitchEnumConstants.java + * @run main SwitchEnumConstants + */ + +import java.util.function.ToIntFunction; + +public class SwitchEnumConstants { + + public static void main(String... args) throws Exception { + new SwitchEnumConstants().run(); + } + + void run() throws Exception { + doRun(this::typeSwitch); + doRun(this::enumSwitch); + } + + void doRun(ToIntFunction c) throws Exception { + assertEquals(0, c.applyAsInt(E.A)); + assertEquals(1, c.applyAsInt(E.B)); + assertEquals(2, c.applyAsInt(E.C)); + assertEquals(3, c.applyAsInt("")); + } + + int typeSwitch(Object o) { + return switch (o) { + case E.A -> 0; + case E.B -> 1; + case E.C -> 2; + case String s -> 3; + default -> throw new IllegalStateException(); + }; + } + + int enumSwitch(Object o) { + if (!(o instanceof E e)) { + return 3; + } + return switch (e) { + case A -> 0; + case B -> 1; + case C -> 2; + }; + } + + + private static void assertEquals(int expected, int actual) { + if (expected != actual) { + throw new AssertionError("expected: " + expected + + ", actual: " + actual); + } + } + + enum E { + A {}, + B {}, + C {} + } +} diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/T8314226.java openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/T8314226.java --- openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/T8314226.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/T8314226.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,167 @@ +/* + * 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 8314226 + * @summary Series of colon-style fallthrough switch cases with guards compiled incorrectly + * @enablePreview + * @compile T8314226.java + * @run main T8314226 + */ + +public class T8314226 { + int multipleGuardedCases(Object obj) { + switch (obj) { + case Integer _ when ((Integer) obj) > 0: + case String _ when !((String) obj).isEmpty(): + return 1; + default: + return -1; + } + } + + int multipleGuardedCases2a(Object obj) { + switch (obj) { + case Integer _ when ((Integer) obj) > 0: + case Float _ when ((Float) obj) > 0.0f: + case String _ when !((String) obj).isEmpty(): + return 1; + default: + return -1; + } + } + + int multipleGuardedCases2b(Object obj) { + switch (obj) { + case Float _ when ((Float) obj) > 0.0f: // reversing the order + case Integer _ when ((Integer) obj) > 0: + case String _ when !((String) obj).isEmpty(): + return 1; + default: + return -1; + } + } + + int multipleGuardedCasesMultiplePatterns(Object obj) { + switch (obj) { + case String _ when !((String) obj).isEmpty(): + case Integer _, Byte _ when ((Number) obj).intValue() > 0: + return 1; + default: + return -1; + } + } + + int singleGuardedCase(Object obj) { + switch (obj) { + case String _ when !((String) obj).isEmpty(): + return 1; + default: + return -1; + } + } + + int multipleCasesWithReturn(Object obj) { + switch (obj) { + case Integer _ when ((Integer) obj) > 0: + case String _ when !((String) obj).isEmpty(): + return 1; + case null: + return 2; + default: + return 3; + } + } + + int multipleCasesWithEffectNoReturn(Object obj) { + int i = 0; + switch (obj) { + case Integer _ when ((Integer) obj) > 0: + case String _ when !((String) obj).isEmpty(): + i = i + 1; + case null: + i = i + 10; + default: + i = i + 100; + } + return i; + } + + int multipleCasesWithLoop(Object obj) { + int i = 0; + switch (obj) { + case Integer _ when ((Integer) obj) > 0: + case String _ when !((String) obj).isEmpty(): + i = i + 1; + case null: + while (true) { + i = i + 10; + break; + } + default: + i = i + 100; + } + + return i; + } + + public static void main(String[] args) { + new T8314226().run(); + } + + private void run() { + assertEquals(1, multipleGuardedCases(42)); + assertEquals(1, multipleGuardedCases("test")); + assertEquals(-1, multipleGuardedCases("")); + assertEquals(1, multipleGuardedCases2a(42.0f)); + assertEquals(1, multipleGuardedCases2a("test")); + assertEquals(-1, multipleGuardedCases2a("")); + assertEquals(1, multipleGuardedCases2b(42.0f)); + assertEquals(1, multipleGuardedCases2b("test")); + assertEquals(-1, multipleGuardedCases2b("")); + assertEquals(1, multipleGuardedCasesMultiplePatterns((byte) 42)); + assertEquals(1, multipleGuardedCasesMultiplePatterns("test")); + assertEquals(-1, multipleGuardedCasesMultiplePatterns("")); + assertEquals(-1, singleGuardedCase(42)); + assertEquals(1, singleGuardedCase("test")); + assertEquals(-1, singleGuardedCase("")); + assertEquals(1, multipleCasesWithReturn(42)); + assertEquals(1, multipleCasesWithReturn("test")); + assertEquals(2, multipleCasesWithReturn(null)); + assertEquals(3, multipleCasesWithReturn("")); + assertEquals(111, multipleCasesWithEffectNoReturn(42)); + assertEquals(111, multipleCasesWithEffectNoReturn("test")); + assertEquals(110, multipleCasesWithEffectNoReturn(null)); + assertEquals(100, multipleCasesWithEffectNoReturn("")); + assertEquals(111, multipleCasesWithLoop(42)); + assertEquals(111, multipleCasesWithLoop("test")); + assertEquals(110, multipleCasesWithLoop(null)); + assertEquals(100, multipleCasesWithLoop("")); + } + + void assertEquals(Object expected, Object actual) { + if (expected != actual) { + throw new AssertionError("Expected: " + expected + ", but got: " + actual); + } + } +} \ No newline at end of file diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/T8314632.java openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/T8314632.java --- openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/T8314632.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/T8314632.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8314632 + * @summary Intra-case dominance check fails in the presence of a guard + * @enablePreview + * @compile/fail/ref=T8314632.out -XDrawDiagnostics T8314632.java + */ +public class T8314632 { + void test1(Object obj) { + switch (obj) { + case Float _ -> {} + case Integer _, CharSequence _, String _ when obj.hashCode() > 0 -> { } // error + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } + + void test2(Object obj) { + switch (obj) { + case Float _ -> {} + case Integer _, CharSequence _, String _ -> { } + default -> throw new IllegalStateException("Unexpected value: " + obj); // error + } + } + + void test3(Object obj) { + switch (obj) { + case Float _, CharSequence _ when obj.hashCode() > 0 -> { } // OK + case Integer _, String _ when obj.hashCode() > 0 -> { } // OK, since the previous case is guarded + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } + + void test4(Object obj) { + switch (obj) { + case Float _, CharSequence _ -> { } // OK + case Integer _, String _ when obj.hashCode() > 0 -> { } // error, since the previous case is unguarded + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } +} diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/T8314632.out openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/T8314632.out --- openjdk-21-21.0.1+12/test/langtools/tools/javac/patterns/T8314632.out 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/patterns/T8314632.out 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,6 @@ +T8314632.java:12:45: compiler.err.pattern.dominated +T8314632.java:20:45: compiler.err.pattern.dominated +T8314632.java:36:29: compiler.err.pattern.dominated +- compiler.note.preview.filename: T8314632.java, DEFAULT +- compiler.note.preview.recompile +3 errors \ No newline at end of file diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java openjdk-21-21.0.2+13/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java --- openjdk-21-21.0.1+12/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java 2024-01-16 16:19:00.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8013852 8031744 + * @bug 8013852 8031744 8225377 * @summary Annotations on types * @library /tools/javac/lib * @modules jdk.compiler/com.sun.tools.javac.api diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/switchexpr/ExpressionSwitchSynchronized.java openjdk-21-21.0.2+13/test/langtools/tools/javac/switchexpr/ExpressionSwitchSynchronized.java --- openjdk-21-21.0.1+12/test/langtools/tools/javac/switchexpr/ExpressionSwitchSynchronized.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/switchexpr/ExpressionSwitchSynchronized.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * 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 8315735 + * @summary Verify valid classfile is produced when synchronized block is used + * inside a switch expression. + * @compile ExpressionSwitchSynchronized.java + * @run main ExpressionSwitchSynchronized + */ +public class ExpressionSwitchSynchronized { + + public static void main(String... args) { + int i1 = 2 + switch (args.length) { + default -> { + synchronized (args) { + yield 1; + } + } + }; + if (i1 != 3) { + throw new AssertionError("Incorrect value, got: " + i1 + + ", expected: " + 3); + } + int i2 = 2 + switch (args) { + case String[] a -> { + synchronized (args) { + yield a.length + 1; + } + } + }; + if (i2 != 3) { + throw new AssertionError("Incorrect value, got: " + i2 + + ", expected: " + 3); + } + } + +} \ No newline at end of file diff -Nru openjdk-21-21.0.1+12/test/langtools/tools/javac/warnings/ThisEscape.java openjdk-21-21.0.2+13/test/langtools/tools/javac/warnings/ThisEscape.java --- openjdk-21-21.0.1+12/test/langtools/tools/javac/warnings/ThisEscape.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/langtools/tools/javac/warnings/ThisEscape.java 2024-01-16 16:19:00.000000000 +0000 @@ -601,4 +601,50 @@ public static final class Sub2 extends ThisEscapeSealed { } } + + // Verify no assertion error occurs (JDK-8317336) + public static class ThisEscapeAssertionError { + public ThisEscapeAssertionError() { + System.out.println((Supplier)() -> this); + } + } + + // Verify no assertion error occurs (JDK-8317336) + public static class ThisEscapeAssertionError2 { + public ThisEscapeAssertionError2() { + ThisEscapeAssertionError2[] array = new ThisEscapeAssertionError2[] { this }; + for (Object obj : array) + ; + } + } + + // Verify no infinite recursion loop occurs (JDK-8317818) + public static class ThisEscapeRecursionExplosion { + private Object obj; + public ThisEscapeRecursionExplosion() { + getObject(); + } + private Object getObject() { + if (this.obj == null) { + this.obj = new Object(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + getObject().hashCode(); + } + return this.obj; + } + } } diff -Nru openjdk-21-21.0.1+12/test/lib/jdk/test/lib/NetworkConfiguration.java openjdk-21-21.0.2+13/test/lib/jdk/test/lib/NetworkConfiguration.java --- openjdk-21-21.0.1+12/test/lib/jdk/test/lib/NetworkConfiguration.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib/jdk/test/lib/NetworkConfiguration.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -176,17 +176,6 @@ return false; } - // On AIX there is a bug: - // When IPv6 is enabled on the system, the JDK opens sockets as AF_INET6. - // If there's an interface configured with IPv4 addresses only, it should - // be able to become the network interface for a multicast socket (that - // could be in both, IPv4 or IPv6 space). But both possible setsockopt - // calls for either IPV6_MULTICAST_IF or IP_MULTICAST_IF return - // EADDRNOTAVAIL. So we must skip such interfaces here. - if (Platform.isAix() && isIPv6Available() && !hasIp6Addresses(nif)) { - return false; - } - if (Platform.isOSX()) { // multicasting may not work on interfaces that only // have link local addresses diff -Nru openjdk-21-21.0.1+12/test/lib/jdk/test/lib/hprof/model/JavaObject.java openjdk-21-21.0.2+13/test/lib/jdk/test/lib/hprof/model/JavaObject.java --- openjdk-21-21.0.1+12/test/lib/jdk/test/lib/hprof/model/JavaObject.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib/jdk/test/lib/hprof/model/JavaObject.java 2024-01-16 16:19:00.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, 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 @@ -192,7 +192,7 @@ if (getClazz().isString()) { JavaThing value = getField("value"); if (value instanceof JavaValueArray) { - return ((JavaValueArray)value).valueString(); + return ((JavaValueArray)value).valueAsString(); } else { return "null"; } diff -Nru openjdk-21-21.0.1+12/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java openjdk-21-21.0.2+13/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java --- openjdk-21-21.0.1+12/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -68,17 +68,17 @@ private static int elementSize(byte type) { switch (type) { - case T_BYTE: - case T_BOOLEAN: + case 'B': + case 'Z': return 1; - case T_CHAR: - case T_SHORT: + case 'C': + case 'S': return 2; - case T_INT: - case T_FLOAT: + case 'I': + case 'F': return 4; - case T_LONG: - case T_DOUBLE: + case 'J': + case 'D': return 8; default: throw new RuntimeException("invalid array element type: " + type); @@ -349,4 +349,18 @@ } return result.toString(); } + + // Tries to represent the value as string (used by JavaObject.toString). + public String valueAsString() { + if (getElementType() == 'B') { + JavaThing[] things = getValue(); + byte[] bytes = new byte[things.length]; + for (int i = 0; i < things.length; i++) { + bytes[i] = ((JavaByte)things[i]).value; + } + return new String(bytes); + } + // fallback + return valueString(); + } } diff -Nru openjdk-21-21.0.1+12/test/lib/jdk/test/lib/jvmti/jvmti_common.h openjdk-21-21.0.2+13/test/lib/jdk/test/lib/jvmti/jvmti_common.h --- openjdk-21-21.0.1+12/test/lib/jdk/test/lib/jvmti/jvmti_common.h 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib/jdk/test/lib/jvmti/jvmti_common.h 2024-01-16 16:19:00.000000000 +0000 @@ -128,6 +128,13 @@ jni->FatalError(msg); } +static void +check_jvmti_error(jvmtiError err, const char* msg) { + if (err != JVMTI_ERROR_NONE) { + LOG("check_jvmti_error: JVMTI function returned error: %s: %s(%d)\n", msg, TranslateError(err), err); + abort(); + } +} static void check_jvmti_status(JNIEnv* jni, jvmtiError err, const char* msg) { diff -Nru openjdk-21-21.0.1+12/test/lib/jdk/test/lib/net/IPSupport.java openjdk-21-21.0.2+13/test/lib/jdk/test/lib/net/IPSupport.java --- openjdk-21-21.0.1+12/test/lib/jdk/test/lib/net/IPSupport.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib/jdk/test/lib/net/IPSupport.java 2024-01-16 16:19:00.000000000 +0000 @@ -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,6 +23,8 @@ package jdk.test.lib.net; +import jdk.test.lib.Platform; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; @@ -48,6 +50,9 @@ private static final boolean hasIPv6; private static final boolean preferIPv4Stack; private static final boolean preferIPv6Addresses; + private static final int IPV4_SNDBUF = 65507; + private static final int IPV6_SNDBUF = 65527; + private static final int IPV6_SNDBUF_AIX = 65487; static { hasIPv4 = runPrivilegedAction(() -> isSupported(Inet4Address.class)); @@ -111,7 +116,6 @@ return preferIPv6Addresses; } - /** * Whether or not the current networking configuration is valid or not. * @@ -154,4 +158,21 @@ out.println("preferIPv6Addresses: " + preferIPv6Addresses()); } + /** + * Return current platform's maximum size for IPv4 UDP send buffer + */ + public static final int getMaxUDPSendBufSizeIPv4() { + return IPV4_SNDBUF; + } + + /** + * Return current platform's maximum size for IPv6 UDP send buffer + */ + public static final int getMaxUDPSendBufSizeIPv6() { + if (Platform.isAix()) { + return IPV6_SNDBUF_AIX; + } else { + return IPV6_SNDBUF; + } + } } diff -Nru openjdk-21-21.0.1+12/test/lib/jdk/test/lib/process/OutputAnalyzer.java openjdk-21-21.0.2+13/test/lib/jdk/test/lib/process/OutputAnalyzer.java --- openjdk-21-21.0.1+12/test/lib/jdk/test/lib/process/OutputAnalyzer.java 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib/jdk/test/lib/process/OutputAnalyzer.java 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -671,15 +671,15 @@ /** * @see #shouldMatchByLine(String, String, String) */ - public OutputAnalyzer shouldMatchByLineFrom(String from, String pattern) { - return shouldMatchByLine(from, null, pattern); + public OutputAnalyzer shouldMatchByLineFrom(String fromPattern, String pattern) { + return shouldMatchByLine(fromPattern, null, pattern); } /** * @see #shouldMatchByLine(String, String, String) */ - public OutputAnalyzer shouldMatchByLineTo(String to, String pattern) { - return shouldMatchByLine(null, to, pattern); + public OutputAnalyzer shouldMatchByLineTo(String toPattern, String pattern) { + return shouldMatchByLine(null, toPattern, pattern); } /** @@ -687,17 +687,17 @@ * {@code pattern} line by line. The whole output could be matched or * just a subset of it. * - * @param from - * The line (excluded) from where output will be matched. - * Set {@code from} to null for matching from the first line. - * @param to - * The line (excluded) until where output will be matched. - * Set {@code to} to null for matching until the last line. + * @param fromPattern + * The pattern of line (excluded) from where output will be matched. + * Set {@code fromPattern} to null for matching from the first line. + * @param toPattern + * The pattern of line (excluded) until where output will be matched. + * Set {@code toPattern} to null for matching until the last line. * @param pattern * Matching pattern */ - public OutputAnalyzer shouldMatchByLine(String from, String to, String pattern) { - return shouldMatchByLine(getOutput(), from, to, pattern); + public OutputAnalyzer shouldMatchByLine(String fromPattern, String toPattern, String pattern) { + return shouldMatchByLine(getOutput(), fromPattern, toPattern, pattern); } /** @@ -705,34 +705,34 @@ * {@code pattern} line by line. The whole stdout could be matched or * just a subset of it. * - * @param from - * The line (excluded) from where stdout will be matched. - * Set {@code from} to null for matching from the first line. - * @param to - * The line (excluded) until where stdout will be matched. - * Set {@code to} to null for matching until the last line. + * @param fromPattern + * The pattern of line (excluded) from where stdout will be matched. + * Set {@code fromPattern} to null for matching from the first line. + * @param toPattern + * The pattern of line (excluded) until where stdout will be matched. + * Set {@code toPattern} to null for matching until the last line. * @param pattern * Matching pattern */ - public OutputAnalyzer stdoutShouldMatchByLine(String from, String to, String pattern) { - return shouldMatchByLine(getStdout(), from, to, pattern); + public OutputAnalyzer stdoutShouldMatchByLine(String fromPattern, String toPattern, String pattern) { + return shouldMatchByLine(getStdout(), fromPattern, toPattern, pattern); } - private OutputAnalyzer shouldMatchByLine(String buffer, String from, String to, String pattern) { + private OutputAnalyzer shouldMatchByLine(String buffer, String fromPattern, String toPattern, String pattern) { List lines = asLines(buffer); int fromIndex = 0; - if (from != null) { - fromIndex = indexOf(lines, from, 0) + 1; // + 1 -> apply 'pattern' to lines after 'from' match + if (fromPattern != null) { + fromIndex = indexOf(lines, fromPattern, 0) + 1; // + 1 -> apply 'pattern' to lines after 'from' match Asserts.assertGreaterThan(fromIndex, 0, - "The line/pattern '" + from + "' from where the output should match can not be found"); + "The line matched with pattern '" + fromPattern + "' from where the output should match can not be found"); } int toIndex = lines.size(); - if (to != null) { - toIndex = indexOf(lines, to, fromIndex); + if (toPattern != null) { + toIndex = indexOf(lines, toPattern, fromIndex); Asserts.assertGreaterThan(toIndex, fromIndex, - "The line/pattern '" + to + "' until where the output should match can not be found"); + "The line matched with pattern '" + toPattern + "' until where the output should match can not be found"); } List subList = lines.subList(fromIndex, toIndex); diff -Nru openjdk-21-21.0.1+12/test/lib-test/TEST.ROOT openjdk-21-21.0.2+13/test/lib-test/TEST.ROOT --- openjdk-21-21.0.1+12/test/lib-test/TEST.ROOT 2023-10-05 13:08:46.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib-test/TEST.ROOT 2024-01-16 16:19:00.000000000 +0000 @@ -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 @@ -29,7 +29,7 @@ keys=randomness # Minimum jtreg version -requiredVersion=7.2+1 +requiredVersion=7.3.1+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them diff -Nru openjdk-21-21.0.1+12/test/lib-test/jdk/test/lib/hprof/HprofTest.java openjdk-21-21.0.2+13/test/lib-test/jdk/test/lib/hprof/HprofTest.java --- openjdk-21-21.0.1+12/test/lib-test/jdk/test/lib/hprof/HprofTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/lib-test/jdk/test/lib/hprof/HprofTest.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,171 @@ +/* + * 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.File; +import java.lang.ref.Reference; +import java.util.Enumeration; +import java.util.concurrent.TimeUnit; + +import jdk.test.lib.Asserts; +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.ProcessTools; + +import jdk.test.lib.hprof.model.JavaClass; +import jdk.test.lib.hprof.model.JavaHeapObject; +import jdk.test.lib.hprof.model.JavaObject; +import jdk.test.lib.hprof.model.JavaValueArray; +import jdk.test.lib.hprof.model.JavaThing; +import jdk.test.lib.hprof.model.Snapshot; +import jdk.test.lib.hprof.parser.Reader; + +/** + * @test + * @bug 8316778 + * @library /test/lib + * @run main HprofTest + */ + +class HprofTestTarg extends LingeredApp { + // Array of primitive types + int[] intArray = new int[2]; + // String + String str = "test_string"; + + public static void main(String[] args) { + HprofTestTarg testObj = new HprofTestTarg(); + + LingeredApp.main(args); + + Reference.reachabilityFence(testObj); + } + +} + + +public class HprofTest { + + public static void main(String[] args) throws Exception { + File dumpFile = new File("Myheapdump.hprof"); + createDump(dumpFile); + test(dumpFile); + } + + private static void createDump(File dumpFile) throws Exception { + LingeredApp theApp = null; + try { + theApp = new HprofTestTarg(); + + LingeredApp.startApp(theApp); + + //jcmd GC.heap_dump + JDKToolLauncher launcher = JDKToolLauncher + .createUsingTestJDK("jcmd") + .addToolArg(Long.toString(theApp.getPid())) + .addToolArg("GC.heap_dump") + .addToolArg(dumpFile.getAbsolutePath()); + Process p = ProcessTools.startProcess("jcmd", new ProcessBuilder(launcher.getCommand())); + while (!p.waitFor(5, TimeUnit.SECONDS)) { + if (!theApp.getProcess().isAlive()) { + log("ERROR: target VM died, killing jcmd..."); + p.destroyForcibly(); + throw new Exception("Target VM died"); + } + } + + if (p.exitValue() != 0) { + throw new Exception("Jcmd exited with code " + p.exitValue()); + } + } finally { + LingeredApp.stopApp(theApp); + } + } + + private static void test(File dumpFile) throws Exception { + Asserts.assertTrue(dumpFile.exists(), "Heap dump file not found."); + + log("Reading " + dumpFile + "..."); + try (Snapshot snapshot = Reader.readFile(dumpFile.getPath(), true, 0)) { + log("Resolving snapshot..."); + snapshot.resolve(true); + log("Snapshot resolved."); + + JavaObject testObj = getTestObject(snapshot); + testPrimitiveArray(testObj); + testString(testObj); + } + + } + + // verifies JavaValueArray.valueString does not throw + // "invalid array element type" exception + private static void testPrimitiveArray(JavaObject obj) { + JavaHeapObject field = getObjectField(obj, "intArray"); + Asserts.assertTrue(field instanceof JavaValueArray); + log("int array: " + ((JavaValueArray)field).valueString()); + } + + // verifies JavaObject.toString returns String value + private static void testString(JavaObject obj) { + JavaHeapObject field = getObjectField(obj, "str"); + Asserts.assertTrue(field instanceof JavaObject); + JavaObject javaObj = (JavaObject)field; + Asserts.assertTrue(javaObj.getClazz().isString()); + log("string: " + javaObj.toString()); + assert(javaObj.toString().contains(new HprofTestTarg().str)); + } + + + private static JavaHeapObject getObjectField(JavaObject obj, String fieldName) { + JavaThing thing = obj.getField(fieldName); + // only non-primitive types are supported + return (JavaHeapObject)thing; + } + + // gets test HprofTestTarg + private static JavaObject getTestObject(Snapshot snapshot) { + String testClassName = HprofTestTarg.class.getName(); + JavaHeapObject testObject = getObjects(snapshot, testClassName).nextElement(); + Asserts.assertTrue(testObject instanceof JavaObject); + return (JavaObject)testObject; + } + + // finds all objects of the specified type + private static Enumeration getObjects(Snapshot snapshot, String className) { + log("Looking for '" + className + "' objects..."); + JavaClass jClass = snapshot.findClass(className); + if (jClass == null) { + throw new RuntimeException("Class '" + className + "' not found"); + } + int instanceCount = jClass.getInstancesCount(false); + if (instanceCount < 1) { + throw new RuntimeException("Not instances of '" + className + "' found"); + } + log("Found " + instanceCount + " instance(s)."); + return jClass.getInstances(false); + } + + private static void log(Object s) { + System.out.println(s); + } +} diff -Nru openjdk-21-21.0.1+12/test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java openjdk-21-21.0.2+13/test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java --- openjdk-21-21.0.1+12/test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-21-21.0.2+13/test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java 2024-01-16 16:19:00.000000000 +0000 @@ -0,0 +1,70 @@ +/* + * 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.io; + +import org.openjdk.jmh.annotations.*; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.SyncFailedException; +import java.util.concurrent.TimeUnit; + +/** + * Tests the cost of FileDescriptor.sync + */ +@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 FileDescriptorSync { + + private FileOutputStream fos; + private FileDescriptor fd; + + @Setup + public void setup() throws IOException { + File tmp = File.createTempFile("FileDescriptorSync", "bin"); + fos = new FileOutputStream(tmp); + fd = fos.getFD(); + } + + @TearDown + public void tearDown() throws IOException { + fos.close(); + } + + @Benchmark + public void sync() { + try { + fd.sync(); + } catch (SyncFailedException e) { + // The test assumes the temp filesystem accepts syncs. + // Avoid failing if it does not, measure the exceptional path then. + } + } + +}